Visual Basic - Крепкий Орешек!

Один из самых информативных и интересных сайтов, посвящённых языку программирования - Visual Basic!

Вводный курс в Visual Basic

  • Введение.
  • Урок № 1. Что такое Visual Basic?
  • Урок № 2. Что может Visual Basic?
  • Урок № 3. Установка и настройка VB.
  • Урок № 4. Для тех, кто никогда не ...
  • Урок № 5. Этапы разработки приложения.
  • Урок № 6. Структура проекта VB.
  • Урок № 7. Среда разработки VB.
  • Урок № 8. Лёгкость работы с кодом.
  • Урок № 9. Из чего состоит код? Переменные.
  • Урок № 10. Массивы, записи, перечисления.
  • Урок № 11. Выражения.
  • Урок № 12. Операторы.
  • Урок № 13. Управляющие структуры.
  • Урок № 14. Процедуры и функции.
  • Урок № 15. Сводим всё вместе.
  • Урок № 16. Отладка программы.
  • Урок № 17. Доводим до ума.
  • Урок № 18. Компиляция.
  • Заключение.
Заходите к нам на сайт! => http://vb.hut.ru !


Введение

Итак, вы решили изучить язык программирования высокого уровня - Visual Basic. Я попытаюсь помочь вам в этом. Наберитесь немного терпения, желания и вперёд, в просторы VB! Ведь Visual Basic - это Крепкий Орешек! ;)

Данный курс предназначен для тех, кто

  1. никогда не программировал, но хочет научиться
  2. программировал на другом языке (Turbo Pascal, QBASIC)
  3. программировал на другом языке высокого уровня (C++, Delphi)

Как видите аудитория довольно широка. От вас требуется только небольшой опыт работы с Windows. И всё.

Этот курс (туториал), конечно не претендует на полноценный учебник по Visual Basic. Он является только как бы введением в VB. Я попытался разобрать основные моменты и приёмы программирования на Visual Basic, зная которые, вы без особого труда сможете пополнять ваши знания.

То, что не вошло в данный материал, вы сможете прочитать в статьях, которые я буду время от времени размещать на сайте.

Удачи! И Вперёд!

Автор данного курса - Волков Антон (aka Funbit).


Что такое Visual Basic?

Перед начинающими программистами всегда встаёт один и тот же вопрос, а именно, какой язык программирования выбрать? На чём программировать? Могу сказать, что лучше начинать с лёгкого и в то же время мощного языка - Visual Basic. Изучив приёмы программирования на VB, вы сможете без особых усилий изучить другие языки, такие как Pascal, C++ и др.

Слово "БЕЙСИК" (BASIC) - "базовый, основной" - образовано из начальных букв английского выражения "Универсальный язык символического кодирования для начинающих". Это "для начинающих" долго вызывало пренебрежение программистов, причём подобное пренебрежение не исчезло до сих пор, несмотря на наличие префессиональных изданий VB.

Первый IMB PC имел 16-разрядный бейсик - BASICA, разработанный IBM, а затем вытесненный миктософтским GW-BASIC и QUICK-BASIC. В последнем была убрана нумерация строк и добавлен компилятор, превращающий бейсик програму в полноценный exe файл. Наконец в 1992г. фирмой Microsoft был выпущен VB 1.0 - очень простой язык программирования для Windows 3.1. Затем были выпущены VB 3.0, VB 4.0, VB 5.0 и наконец VB 6.0. Последние две версии мало чем отличаются, в шестой версии улучшено ядро и добавлены несколько новых функций. Существует ещё язык макросов для приложений Microsoft Office (Word, Excel и т.п.). Он называется VBA (Visual Basic for Application). С его помощью можно манипулировать приложениями Office.

Приложения написанные на Visual Basic отличаются от обычных приложений тем, что требуют для своей работы библиотеку msvbvmX0.dll, которая должна присутсвовать в каталоге Windows\System. В роли X выступает версия компилятора VB. Для VB5 - msvbvm50.dll, для VB6 - msvbvm60.dll. Эти библиотеки идут в комплекте с WinME (обе) и Win98 (только msvbvm50.dll), и естественно с более новыми версиями этих ОС. Вы не должны бояться того, что вместе с вашим приложением, вам придётся таскать за собой эту библиотеку. Она есть уже у 90% пользователей. Но если вы всё-таки боитесь за аудиторию, то можете зашить библиотеку прямо в EXE файл. Правда для этого придётся использовать средства не входящие в состав VB. Например, это можно сделать с помощью программы Fusion (фирмы BitArts).

Некоторые также считают, что приложения VB - это не полноценные программы, а лишь псевдокод, который при запуске выполняется интерпретатором. Это не совсем так. Если вы компилируете программу в Native Code, то полученный EXE - полноценное приложение Win32, которое просто использует функции msvbvm библиотеки. А вот P-Code является псевдокодом. Вид компиляции вы можете указать в меню Project->ProjectX Properties...

Среда Visual Basic может с успехом использоваться начинающими пользователями для познания секретов программирования и увлекательных занятий по созданию несложных (поначалу) приложений и, в то же время, предоставляет мощные инструменты разработки опытным программистам. Развитая справочная система позволит при построении приложения и работе в Visual Basic найти выход из любой ситуации и получить ответ на любой вопрос. Начинать работать с Visual Basic можно практически с любым уровнем подготовки.

Visual Basic доступен в трех редакциях, каждая из которых обеспечивает определенный набор инструментов разработки. Это

Standard Edition

Visual Basic Standard Edition позволяет создавать достаточно мощные приложения для Microsoft Windows 95 и Windows NT. Эта редакция включает все встроенные элементы управления Visual Basic, включая связанные (data-bound) элементы управления.

Professional Edition

Редакция Professional обеспечивает полно-функциональный набор инструментальных средств для разработки профессиональных решений, предназначенных для тиражирования. Она включает все возможности Standard Edition плюс дополнительные элементы управления ActiveX, включая элементы управления для Internet и генератор отчетов Crystal Reports для Visual Basic (рассматривается в главе 5).

Примечание: Элемент управления ActiveX — подключаемый объект, который можно помещать в форму, чтобы активировать или расширить взаимодействие пользователя с приложением. С элементами управления ActiveX ассоциируются события, и они могут быть включены в другие элементы управления. Эти элементы управления имеют расширение имени файла .осх.

Enterprise Edition

Редакция Enterprise позволяет создавать распределенные приложения силами группы разработчиков. Она обеспечивает все возможности редакции Professional и включает также дополнительные функции, такие, как Automation Manager, Component Manager, инструментальные средства управления базами данных и Microsoft Visual SourceSafe — проект-ориентированная система управления версиями продуктов.

Идём дальше. Что же может Visual Basic?


Установка и настройка VB

Установка Visual Basic не отличается особой сложностью, всё стандартно. В процессе инсталляции вас попросят указать компоненты, которые будут установлены на ваш компьютер. Если на жёстком диске есть место, то лучше выбрать все компоненты, чтобы потом их не пришлось добавлять. Здесь следует отметить то, что версия VB 5.0 поставляется с файлами помощи (примерно 15Мб), а помощь для VB 6.0 идёт в комплекте с MSDN, который поставляется на трёх дисках. Поэтому если у вас шестая версия, записанная на одном диске, то будьте уверены, помощи там не будет. Но вполне можно взять помощь от пятой версии и использовать её для VB 6.0. После установки VB перезагрузите компьютер.

Итак, компьютер перезагружен. Перед работой с VB его необходимо настроить. Для этого запустите VB (Пуск->Программы->Microsoft Visual Basic 6.0->Visual Basic 6). Зайдите в меню Tools->Options. Поставьте галочку "Require Variable Declaration". Это избавит вас от лишних ошибок при автоматическом определении переменных. Далее на вкладке Editor Format, в списке Font укажите Courier New Cyr. Если этого не сделать, то VB не будет корректно отображать кириллицу. Также рекомендую установить цвет зарезервированных слов в ярко-синий. Для этого выберите в списке Code Colors Keyword Text и в поле Foreground укажите ярко-синий цвет (седьмой снизу). Вот и всё! Visual Basic готов к работе!

Следующая глава предназначена для тех, кто никогда не программировал. Если вы знакомы с программироваем, то смело можете пропустить этот урок.


Для тех, кто никогда не ...

Эта маленькая глава для тех, кто никогда не программировал. Хотя таких людей не существует! Ведь вы программируете своё поведение, учитывая разные варианты дальнейшего хода событий и изменяя "программу" в зависимости от обстоятельств. Например, если вы заболели, то вы наверняка не пойдёте на работу (или в школу) и т.п. Всё отличие житейской программы от программирования на компьютере состоит в уровне формализации порядка действий, необходимые для достижения результата. Ведь компьютер - это машина, он не поймёт вас с полуслова, более того, он вообще вас не может понимать! Он только выполняет заложенные в него инструкции и команды для работы с двоичными числами.

Для написания более или менее сложной программы необходимо сначала составить условную последовательность действий на бумаге. Например, "как сварить щи?":

Житейский вариант программы:

Купить на рынке овощей подешевле, сметаны, всё почистить, порезать, налить воды, поставить на плиту и варить полчаса. Ещё не забыть посолить.

Формализованный вариант (Алгоритм):

  1. Для всех продовцов овощей от первого до последнего
  2. Если овощи у данного продавца дешевле, чем у ранее проверенных, то записать его номер на бумажку вместо ранее на ней записанного
  3. Следующий продавец (см. п.2, если они ещё остались)
  4. Купить овощи у продавца с номером, записанным на бумажке
  5. Купить сметану
  6. Выполнять очистку овощей, пока видна кожура и повреждения
  7. Увеличиваем срезаемый слой на миллиметр
  8. Возврат и проверка условия в п.6
  9. Для всех купленный овощей от первого до последнего
  10. Разделить плод на 40 частей
  11. Следующий (см. п.10, если они ещё остались)
  12. Поместить в кастрюлю. Налить воды, включить газ
  13. Таймер включить
  14. Если таймер показывает, что прошло полчаса, то газ выключить
  15. Если соль отсутствует в щах, то перейти к обработке ошибки по п.16, иначе перейти к п.17
  16. Ввести соль
  17. Конец работы программы

Простота написания программ на бейсике состоит в том, что в качестве команд он использует английские слова, эквивалентные русским из формализованного варианта, т.е. если переводчик, не знакомый с информатикой, переведёт его на английский, то получится программа на бейсике. Работать она не будет. Закон программирования гласит: "Ни одна, даже самая простая программа, не работает сразу после написания". Любую программу необходимо отлаживать. (обезжучивать - debug (bug-жук)). На этот счёт имеется ещё закон: легче написать свою собственную программу, чем разбирать и исправлять чужую. Отладка программы по ощущениям напоминает проталкивание тяжёлого грузовика по размытой дороге: в ход идут одни доски, камни и лопата, и так до тех пор, пока программа не начнёт правильно работать. Если говорить на языке алгоритма, то получится следующее:

  1. Запустить программу
  2. В случае сбоя или неправильной работы найти причину ошибки
  3. Устранить ошибку, стараясь не внести новых
  4. Продолжать по п.1 до тех пор, пока не будут устранены все ошибки

Если вы усвоили вышеизложенный материал, то можете переходить непосредственно к изучения языка Visual Basic. Для этого переходите к пятому уроку.

В статье используются вырезки из журнала ДК.


Этапы разработки приложения

В Visual Basic, как и во многих других языках, предназначенных для написания приложений под Windows, используется событийно-управляемая модель программирования. В "старых" версиях бейсика, таких как QBasic, использовалась плоская структура написания программы. Каждая программа начиналась и заканчивалась в определённых местах. Вся программа выполнялась последовательно, и иногда, возможно, вызывались пользовательские процедуры и функции. Т.е. если программу "запускали", то она сразу начинала выполняться, и , дойдя до конца, завершалась. В Visual Basic это происходит совсем иначе. Дело в том, что ОС Windows имеет GUI (Graphical User Interface), т.е. графический интерфейс пользователя, в котором используются снандартные элементы управления, такие, как окна (они же формы), кнопки, списки, поля, для ввода текста и т.п. В любом языке высокого уровня программа строится на основе этих элементов. Итак, разработка приложения на VB состоит из следующих этапов:

  1. Продумывания программы (подумать, что программа должна делать, решить перед собой задачи, реализовать их мысленно, продумать структуру данных, и т.д.).
  2. Проектирование интерфейса, т.е. помещение на форму нужных управляющих элементов, кнопок, списков и т.п. Этот этап называется составлением скелета программы.
  3. Написание программного кода, связывающего помещённые на форму управляющие элементы, т.е. "наращивание плоти на скелет".
  4. Отлаживание программы. Этот этап часто занимает больше времени, чем предыдущие.
  5. Окончательная компиляция и, если это необходимо, создание дистрибутива (т.е. установочного файла setup.exe).

Эти этапы всегда необходимо держать в памяти, т.к. они используются при написании любой программы. Порядок этапов тоже важен. Например, нельзя сначала написать код программы, а только потом разрабатывать интерфейс пользователя (есть конечно редкие исключения, например, когда программа вообще не имеет интерфейса, или когда вы пишите процедуру, независимую от интерфейса программы). Описывать первый этап не имеет смысла, т.к. он вполне ясен. Остановимся подробнее на втором этапе.


Структура проекта VB

Перед рассмотрением вопроса проектирования интерфейса приложения на Visual Basic, необходимо представлять, из чего вообще состоит этот проект?

В Visual Basic любой проект состоит из следующих файлов:

  • файл каждой формы (расширение frm). Это обычный ASCII текстовый файл, в котором записан весь код, помещённый в форму, а также свойства всех помещённых на форму элементов управления и самой формы тоже.
  • файл каждой формы, содержащий бинарную информацию (например картинку в PictureBox) (расширение frx)
  • файл проекта, содержащий информацию о проекте (расширение vbp)
  • информация о рабочей области проекта (workspace) (расширение vbw)

Это необходимый минимум. (Хотя, бывают и исключения, например, когда в проекте не используются формы. Тогда вместо frm файла, будет bas файл.)

Далее перечислим дополнительные файлы, которые могут быть подключены к проекту:

  • файл каждого модуля (расширение bas) Это текстовый файл.
  • файл каждого модуля классов (расширение cls). Это текстовый файл.
  • файл каждого дополнительного элемента управления (расширение ctl) Это тоже текстовый файл.
  • файл ресурсов (расширение res)
  • другие файлы (ocx, tlb, и т.д...)

Запоминать назначение всех этих файлов не обязательно, достаточно запомнить 2 файла: frm-файл, в котором хранятся код формы и свойства всех помещённых на данную форму элементов управления. И bas-файл - модуль. В нём могут быть объявлены глобальные переменные, константы, функции и т.д. Короче, только код. Без элементов управления.

Теперь, приблизительно представляя структуру проета на Visual Basic, можно переходить к рассмотрению вопроса проектирования интерфейса.


Среда разработки VB

Для того, чтобы понять как проектировать интерфейс, разберём для начала среду разработки Visual Basic. Запустите VB. Перед вами появится окошко, в котором вам попросят указать тип проекта. Укажите тип "Standart EXE" и нажмите ОК. На экране вы увидите следующее окно:

В левой части расположена панель с доступными элементами управления, с которой вы можете перетаскивать нужные элементы на форму. В центре находится форма (окно) вашего приложения. Имя новой формы - Form1. Вверху расположена панель инструментов среды разработки. Описание всех пунктов меню (для VB5) и всех кнопок панели управления вы можете прочитать здесь. Справа расположены окна проекта (Project) и свойств текущего объекта (Properties). Здесь необходимо отметить, что все объекты в VB (впрочем как и в других языках высокого уровня) имеют свойства и методы. Свойства — значения, которые устанавливаются для определения вида и поведения объекта. Методы — программные процедуры, обеспечивающие выполнение объектом некоторых предопределенных действий. Например, форма обеспечивает метод Show, который обусловливает вывод формы на экран. Главное преимущество работы с объектами в том, что объекты обеспечивают программный код, который уже не требуется писать разработчику. Ему просто нужно установить свойства объекта и вызвать методы объекта, чтобы побудить объект выполнить требуемые функции. Некоторые свойства можно отредактировать только в период выполнения программы (RunTime). Многие объекты имеют однинаковые свойства. Например, свойство Caption. У формы (Form) Caption - это заголовок окна, а у элемента метки (Label) - это текст внутри метки. Постепенно вы привыкните к таким обозначениям и в последствии сможете разобраться с любым, незнакомым вам элементом управления.

Итак, для того чтобы поместить на форму нужный вам элемент, необходимо проделать следующее: нажать мышкой на нужный вам элемент на панеле слева, например, на кнопку (Command Button). После нажатия кнопка окажется вдавленной. Теперь поместите курсор мыши на форму и растяните мышкой прямоугольник. В результате этих манипуляций у вас на форме появится кнопка, имеющая размеры прямоугольника. Если вам понадобится изменить размеры кнопки, то необходимо выделить кнопку нажатием левой кнопки и растянуть кнопку за маркеры, расположенные на вершинах кнопки. Переместить кнопку в другое место можно обычным перетаскиванием (Drag&Drop). Необходимо отметить, что не все элементы управления имеют размеры. Например, Timer. Такие элементы не видны в процессе работы приложения, но выполняют определённые функции.

Чтобы изменить свойства элемента управления необходимо выделить его и изменить нужное свойство в окне Properties. Давайте, к примеру, поменяем заголовок формы. Ткните левой кнопкой мыши в любое место формы и в найдите в окне Properties свойство Caption. Измените его, например, на "Это моя первая форма". Заголовок будет меняться по мере ввода текста.

Теперь давайте запустим программу. Для этого нажмите на кнопку Start, расположенной на панели инструментов и имеющей иконку кнопки Play (как на магнитофоне). После непродолжительной компиляции, перед вами появится окно вашей программы! Причём вы можете его передвигать, менять размеры, минимизировать! И всё без единой строчки кода! Фантастика! :)

Теперь закройте программу. Это можно сделать двумя способами - нажать на крестик в правом верхнем углу формы или нажать на кнопку End, имеющей иконку кнопки Stop.

После закрытия программы вы вернётесь в среду разработки VB. Кстати, обратите внимание на окошко Project. В нём показан только один файл - Form1. Давайте добавим ещё одну форму к нашему проекту. Для этого выберите в меню Project->Add Form. Перед вами появится окно Add Form, в котором вам предложат выбрать вид новой формы. Дважды кликните на иконке с надписью Form. Перед вами появится новая форма. Её имя Form2. Но куда же делась старая, спросите вы? Для того, чтобы увидеть нашу старую форму, нужно дважды щёлкнуть по строчке Form1 в окне Project. Щёлкнув, вы сразу увидите нашу первую форму. Обратите внимание на 2 кнопочки в окне Project. View Object и View Code. Эти кнопочки вам очень пригодятся в дальнейшем. С помощью них вы можете переключаться между двумя режимами:

  1. просмотром формы, для проектированием её интерфейса
  2. просмотром кода формы

Нажмите на кнопку View Code. Если вы настроили Visual Basic, согласно
уроку 3, то в коде вы увидите только одку строчку:

Option Explicit

Эта строчка выделена синим цветом, т.к. это зарезервированное слово VB. Если такая строчка есть в начале модуля, то переменные нельзя будет использовать до тех пор, пока они не объявлены оператором Dim. (как в C).

Теперь давайте сохраним наш проект. Для этого нажмите на кнопку Save Project (на панели пятая). Вас попросят указать каталог для сохранения и имя файла для формы №1 (Form1.frm). Затем файл Form2.frm. И наконец файл Project1.vbp (vbp - Visual Basic Project). Всё, проект сохранён. Теперь вы можете открыть его в дальнейшем кнопкой Open Project. Открывать нужно файл с расширением vbp (Visual Basic Project). Здесь могу дать один очень важный совет - почаще сохраняйтесь! А то мало ли что... То Windows глюкнет, то свет выключат...

Как видите, ничего сложного. Просто нужно привыкнуть к интерфейсу среды Visual Basic. На этом мы закончим этот урок. В качестве домашнего задания, добавьте к проекту модуль (Project->Add Module). И сохраните проект.

В следующей главе вы узнаете, как приятно редактировать код в Visual Basic.


Лёгкость работы с кодом в VB

В этой маленькой главе я бы хотел рассказать про лёгкость работы с кодом в Visual Basic.

Intellisence

Технология Intellisence сильно облегчит вам жизнь в процессе программирования на VB. Эта технология Microsoft позволит вам избежать ввода большого количества кода и его корректировки. Intellisence выводит небольшое всплывающее окно с полезной информацией о текущем объекте. Наверняка вы уже видели такое окно. Такие окна бывают 3-х видов:

  1. QuickInfo. Выдаёт информацию о синтаксисе текущего оператора Visual Basic. Где бы вы не ввели имя оператора (функции) и поставили после имени пробел или октрывающую круглую скобку, то Visual Basic незамедлительно покажет информацию о синтаксисе этого оператора. Вот пример:

  2. List Properties/Methods. Это свойство облегчит вам работу с объектами в Visual Basic. После того, как вы поставите точку после имени какого либо объекта, VB сразу же покажет вам список всех доступных свойств и методов этого объекта:

    Свойства имеют иконку: , а методы - [image].

  3. Available Constants. Эта функция выводит окно доступных констант. Например, если вы поставите знак равенства после Boolean переменной, то Visual Basic выдаст вам окно, где вы сможете выбрать из двух значений (True/False) нужное. Вам даже не придётся ничего набирать на клавиатуре!

  4. Также, Если нажать Ctrl+J, то VB выдаст список всех определенных в программе свойств, методов, констант, типов и т.д, включая встроенные в сам Visual Basic.

Также для новичков может быть полезна функция Auto Syntax Check, которую можно включить в Tools->Options. Если галочка стоит, то Visual Basic будет следить за правильностью набранного кода в Visual Basic. Если мы наберёте строчку неверно, то VB предупредит вас об этом, выдав окно с сообщением.

Ещё Visual Basic постоянно следит за красивостью кода :). Т.к. Visual Basic не различает большие и маленькие буквы, он будет постоянно корректировать имена переменных и функций в коде программы, чтобы они выглядели именно так, как указано в их определении. Например, если вы объявите переменную

Dim myVar As String

А затем в коде программы введёте:

MYVAR = "VB"

То после того, как курсор редактирования перейдет на следующую (или просто другую) строчку, VB изменит код следующим образом:

myVar = "VB"

Т.е. имя переменной всегда будет написано так, как определено в операторе Dim. Это очень хорошая функция VB.

Также Visual Basic подсвечивает цветами некоторые участки кода. Синим цветом выделяются зарезервированные слова Visual Basic. Сине-зелёным цветом (если его можно таким назвать) комментарии, остальное чёрным. Комментарии - это всё, что находится после символа ' (апостроф). При компиляции комментарии игнорируются, но при просмотре кода они очень полезны. Советую комментировать код, особенно в тех местах, где сам чёрт сломит ногу! ;). Примеры подстветки:

Dim prgVariable As Long ' это комментарий

Отступы

Про отступы я бы хотел поговорить отдельно. Отступы ОЧЕНЬ выжны при программировании. Пожалуйста, НИкогда НЕ забывайте про них! Они помогут при просмотре вашего кода. Особенно они полезны в сложных ветвлениях и циклах. Давайте рассмотрим пример:

If Form1.Visible = False Then
If a = b Then
For c = 1 To 5
If b > c Then Exit Sub
Next c
End If
End If

Согласитесь, понять в таком коде что выполняется после чего - оччень сложно. Но если мы поставим отступы, то всё сразу станет ясно!:

If Form1.Visible = False Then
    If a = b Then
        For c = 1 To 5
            If b > c Then Exit Sub
        Next c
    End If
End If

Как видите, теперь сразу видно, что второй If выполниться только при выполнении первого условия, что цикл находится внутри ветвления, и т.д.

Visual Basic предоставляет возможность сделать отступ сразу для участка кода. Для этого необходимо выделить этот участок (несколько строк) и нажать Tab. Все выделенные строки сдвинуться вправо. Если вам понадобиться сдвинуть код влево, нажимайте Shift+Tab. Всегда помните про отступы!

Дальше ещё интереснее!


Из чего состоит код?

Итак, мы научились проектировать интерфейс программы. Но для полноценной программы этого не достаточно. Нужно написать код программы, который будет манипулировать элементами управления и производить какие-то вычисления. Это самый сложный этап.

Во всех языках высокого уровня программный код состоит из:

  • Переменных
  • Выражений
  • Операторов
  • Управляющих структур
  • Функций
  • Классов и объектов

Опишем каждый тип подробнее:

Переменные.

В Visual Basic переменые хранят информацию (значения). При их использовании Visual Basic резервирует область в памяти компьютера для хранения данной информации. Каждая переменная имеет своё имя. Оно может достигать 255 символов в длину, начинается всегда с буквы латинского алфавита, за которой могут следовать другие буквы, цифры и знак подчёркивания. Регистр символов значения не имеет. Приведём несколько примеров имён переменных:

numOfLetters - подходит
2Bottle - неверно, т.к. начинается не с буквы
ThisIsVeryLongName - подходит, длина 18 символов
sng.Cos - не подходит, т.к. используется точка

Именование переменных и функций очень важная штука. Я рекомендую придерживаться венгерского соглашения:

Тип | Схема именования | Пример
Константа | Имя константы должно состоять только из заглавных букв. | HWND_BROADCAST
Переменная | Имя переменной должно начинаться с маленькой буквы, далее следующий слова с большой. | numOfFonts
Функция | Имя функции должно начинаться с заглавной буквы, далее следующие слова тоже с заглавной. | SetForegroundWindow

Постарайтесь чтобы именование переменных согласно такой схеме у вас вошло в привычку. Я советую, но не настаиваю. Не нравится - пожалуйста, нызывайте как вам угодно, вот только так вы никогда не станете профессиональным программистом.

Каждая переменная имеет определённый тип. Всего в VB 14 типов переменных. Кроме того, программист может определить и свой тип. Перечислим основные типы переменных VB:

Byte - предназначен для хранения целых чисел от 0 до 255. Если переменной такого типа присвоить значение, выходящее за эти пределы, то Visual Basic сгенерирует ошибку.

Integer - предназначен для хранения целых чисел в диапазоне
-32768 до +32767, т.е. размер памяти, выделяемой под такую переменную состовляет 2 байта. (256*256=65536). Символ для обозначения - "%". Зачем он нужен, мы рассмотрим далее.

Long - предназначен для хранения целых чисел в диапазоне
-2147483648 до +2147483647, т.е. размер памяти, выделяемой под такую переменную состовляет 4 байта. (65536*65536=4294967296). Символ для обозначения - "&".

String - предназначен для хранения строковой (символьной) информации, т.е. попросту говоря - текста. Может хранить до 2 Гб. текста. Символ для обозначения - "$".

Single - предназначен для хранения дробных чисел, с точностью до 7 цифр. Диапазон отрицательных значений от -3.402823Е38 до -1.401298Е-45. Диапазон положительных значений от 1.401298Е-45 до 3.402823Е38. Длина числа может достигать 38 знаков. Занимает 4 байта памяти. Вычисления с данными переменными будут приблизительными и менее быстрыми, чем с переменными целого типа. Символ для обозначения - "!".

Double - предназначен для хранения дробных чисел, с точностью до 16 цифр. Диапазон отрицательных значений
от 1.79769313486232Е308 до -4.94065645841247Е-324.
Диапазон положительных значений
от 4.94065645841247Е-324 до 1.79769313486232Е308.
Длина числа может достигать 300 знаков. Занимает 8 байта памяти. Вычисления с данными переменными будут приблизительными и менее быстрыми, чем с переменными целого типа. Используется для научных рассчётов. Символ для обозначения - "#".

Currency - Данный тип создан для того, чтобы избежать ошибок при преобразовании чисел из десятичной формы в двоичную и наоборот (Невозможно представить 1/10 как сумму 1/2, 1/4 и т.д). Данный тип может иметь до 4 цифр после запятой, и до 14 перед ней. Внутри данного диапазона вычисления будут точными. Вычисления выполняются так же медленно, как и в случае переменных Single и Double. Данный тип очень подходит для финансовых расчётов. Символ для обозначения - "@".

Date - Этот тип данных позволяет хранить значения времени и даты в промежутке от полуночи 1 января 100 года до полуночи 31 декабря 9999 года. Если переменной присвается только значение даты, то время равняется 00:00.

Boolean - очень важный и распространённый тип данных. Позволяет хранить так называемые булевы значения, т.е. только два значения - True и False. (По русски Правда и Ложь). Используется тогда, когда вам нужно хранить только значение Да или Нет.

Variant - Переменная типа Variant может содержать данные любого типа. Visual Basic автоматически производит необходимые преобразования данных, поэтому не стоит беспокоится об этом. Использование такого типа данных замедляет работу программы, т.е. требуется время и ресурсы для преобразования типов. Поэтому рекомендую всегда воздерживаться от применения этого типа данных, за исключением специфических случаев, например, возвращение функцией массива возможно только при использовании типа Variant.

В Visual Basic переменные объявляются с помощью оператора Dim, после которого следует As и Имя_Типа переменной. Например:

Dim
        a As Long
Dim b As Byte
Dim c As Long
Dim numOfLetters As Long
Dim myString As String
Dim isLoaded As Boolean

Если не указывать As Имя_Типа, то переменная будет объявлена как Variant.

После объявления переменной ей присваивается значение по умолчанию. Для стоки это - "" (пустая строка). Для чисел - 0. Для Boolean - False. Переменная может быть использована сразу после объявления.

Переменные можно объявлять и в одной строчке, разделяя объявления запятыми:

Dim a As Long, Dim b As Integer

Здесь очень важно заметить следующую особенность. Логично было бы объявить 3 переменные типа Long следующим образом:

Dim a, b, c As Long

Такая привычка могла перейти, например, из языка C. Там все переменные действительно имели бы тот тип, который указан после последней переменной. Но не в Visual Basic! В результате такого объявления VB объявит 3 переменные, первая и вторая будут иметь тип Variant, и только третья - Long! Запомните это! А вообще, лучше объявлять каждую переменную в отдельной строчке. И, если необходимо, то логически отделить эти объявления можно просто вставив пустую строку между теми объявлениями, которые вы хотите отделить логически. Например, так:

Dim a As Long
Dim b As Long

Dim myString1 As String
Dim myString2 As String

Такие логические пробелы между строчками необходимы для избавления кода от его монотонности.

Присвоить значение переменной можно при помощи знака равно "=". Например:

a =
        1234567
b = 234
c = 133
myString = "Visual Basic рулит"
isLoaded = True

В данном примере переменным присваивались константы. Но часто бывает необходимо присвоить одной переменной значение другой. Это делается следующим образом:

a = b
' можно, т.к. переменная b "умещается"
' в тип Long (234<4294967296)

a = b + c
' теперь в a хранится сумма b + c.

b = c
' тоже возможно (133 < 255)

b = a
' нельзя, т.к. переменная a не укладывается
' в диапазон [0-255]. Произойдёт ошибка.

myString = a
' Visual Basic сам преобразует число 1234567
' в строку "1234567", а потом присвоит это значение
' переменной myString. Также возможно обратное действие.

isLoaded = True
' всё ОК

myString = myString & " однозначно!"
' здесь происходит слияние двух строк, в результате чего
' переменная myString содержит строку:
' "Visual Basic рулит однозначно!".

isLoaded = a
' возможно, т.к. Visual Basic сам преобразует тип Long
' в тип Boolean. isLoaded будет содержать True.
' Почему не False?
' Потому, что в VB False - это нуль, а любое,
' не нулевое значение - True

Выше, при описании типов переменных я указывал символ для обозначения. Этот символ можно (а иногда и нужно) использовать для объявления переменной, но без использования зарезервированных слов As Тип. Т.е. к примеру:

Dim myLongParam&
Dim myString$

Здесь объявлены 2 переменные, первая имеет тип Long, вторая - String. Также можно употребрять эти спец. символы для явного указания типа константам, например:

Call MyProc (myParam1, myParam2, 5&)

Здесь, при вызове процедуры MyProc, последний параметр имеет тип Long. Если бы мы не указали значок &, то он (параметр) имел бы тип Byte. Это необходимо при использовании API функций.

Выше я уже отмечал, что Visual Basic часто, незаметно для разработчика, занимается преобразованием типов переменных на лету. К примеру, мы рассматривали такой пример:

myString = a

Переменная a имеет тип Long, а myString - String. Visual Basic сам преобразует переменную a в тип String, а затем присвоит значение переменной MyString. Это необходимо знать. Также, Visual Basic предоставляет в ваше распоряжение несколько функций преобразования типов: CLng, CBool, CDate, CStr и т.д. Каждая функция преобразует выражение к соответствующему типу. Рассмотрим распространённую ошибку программиста на VB. Пусть у нас есть код типа:

Dim
        a As Byte
Dim b As Byte
Dim c As Long

a = 200
b = 200

c = a + b

Казалось бы, что если запустить такой код на выполнение, то в переменной c будет находиться значение 400 (200 + 200). Но не тут-то было :(. Visual Basic на строке c = a + b сгенерирует ошибку Overflow (Переполнение). Дело в том, что в выражении справа от знака равно складываются 2 переменные типа Byte, и Visual Basic решает, что после вычисления этого выражения, должен остаться тот же тип - Byte. Но если вспомнить то, что тип Byte может хранить значения в диапазоне 0-255, можно понять почему VB генерирует Overflow (Переполнение). 400 далеко выходит за диапазон Byte... Здесь может возникнуть вопрос: "А как же быть? Объявлять переменные a и b типом Long?". Можно поступить и так. А можно воспользоваться функций преобразования типа CLng. Тогда работоспособный код будет выглядеть следующим образом:

Dim a As Byte
Dim b As Byte
Dim c As Long

a = 200
b = 200

c = CLng(a) + CLng(b) 'Всё в порядке, 400 - входит в тип Long

Немного о константах:

В Visual Basic можно объявлять не только переменные, но и константы. Константа как и переменная, тоже хранит некоторое значение, но в отличие от переменной хранимое значение не может изменяться. Чтобы объявить константу необходимо использовать зарезервированное слово Const, за которым следует имя и значение (и возможно тип) константы:

Const PI = 3.1415

Здесь объявлена константа c именем pi и значением 3.1415. После объявления она может быть использована по назначению.

Можно отметить следующую особенность VB: для констант с плавающей точкой тип по умолчанию - Double, для целых чисел - Integer. (Это легко можно проверить встроенной функций VB - VarType). Для того, чтобы явно задать тип константы, необходимо после имени задать тип, к примеру

Const PI As Long = 3 ' PI = 3, PI имеет тип Long

В Visual Basic существует очень много встроенных констант, которые с легкостью могут быть использованы в ваших программах. Например, константа vbNewLine - содержит 2 символа, с ASCII кодами 13 и 10, т.е. переход на новую строку. Список констант можно посмотреть в Object Browser'е. Для его вызова необходимо нажать F2, находясь в среде Visual Basic.

"Видимость" переменных:

Объявлять переменные можно в самых разных местах:

  1. Внутри процедуры (или функции). В этом случае переменная будет "видна" только в коде этой процедуры (или функции). Если вы попытаетесь обратиться к такой переменной внутри кода другой процедуры, то Visual Basic сгенерирует ошибку.

  2. В самом верху кода формы, т.е. сразу после оператора Option Explicit. Это место называется разделом General Declarations (раздел Глобальных Объявлений). Такие переменные будет "видны" в любом месте кода формы. Т.е. в любой процедуре (или функции) формы. Переменные в данном месте могут быть объявлены с помощью зарезервированных слов Private и Public. Рассмотрим 3 определения:

    Dim myLocalVar1 As Byte
    Private     myLocalVar2 As Integer
    Public     myGlobalVar1 As Long

    Первые 2 определения абсолютно эквивалентны. Переменные объявленные таким образом будут видны в любом месте кода формы. Но только той формы, где они объявлены. В других формах обратиться к таким переменным будет нельзя.

    Третья переменная будет видна всему приложению в любом месте. Правда, чтобы добраться к такой переменной из кода другой формы, необходимо перед именем переменной указать ещё и имя формы, где эта переменная объявлена, например:

    Form1.myGlobalVar1 = 234

  3. В разделе General Declarations модуля. Здесь действуют те же правила, что и в разделе General Declarations формы. Private (или Dim) будут "видны" только в коде модуля. А Public - везде. Отличие наблюдается только в способе доступа к переменной. Здесь не обязательно указывать имя модуля перед такой переменной. Можно просто указать её имя и всё. Хотя я не рекомендую этого делать, т.к. теряется наглядность. И, к тому же, если у вас 2 модуля, в которых объявлены переменные с одинаковыми именами, то добраться к ним можно только указав имя соответствующего модуля перед именем переменной.

Период существования переменных:

Период существования переменной означает, как долго переменная является доступной.

Переменные, объявленные в процедуре (или функции) будут "живы" только пока выполняется эта процедура (или функция). При выходе из процедуры - переменная удаляется. При очередном вызове этой процедуры - переменная заново инициализируется. Кстати, к словам Private, Public и Dim, в процедурах и функциях можно использовать зарезервированное слово Static. Такая переменная при повторном вызове этой процедуры не будет заново инициализироваться. Она будет сохранять то значение, которое было в ней после предыдущего вызова. (такие переменные очень удобно использовать в обработке события Timer'а). Например:

Static myStat As String ' Private Static переменная

Переменные уровня формы будут "живы" только пока "жива" форма. Как только объектная переменная формы будет установлена в Nothing (или после выполнения оператора Unload), все переменные уровня этой формы удаляются.

Переменные уровня модуля "живы", пока "живёт" ваше приложение. Т.е. "живы" всегда.

Некоторые замечания:

Перед использованием переменной, её обязательно нужно объявить. Это избавит вас от лишних ошибок.

Переменным нужно давать осмысленные имена. Т.е. старайтесь не использовать имена типа a1,a2,a3,ab,ccc и т.п. Поверьте, рано или поздно вы запутаетесь в своей же программе! Лучше всего переменным давать английский эквивалент того, что хранит данная переменная. Например, для хранения некоторой суммы денег, переменная может быть названа как cashMoney. Если у вас английским не очень, то можете использовать транслит, т.е. переменную назвать, например как summaDeneg. Ну и т.п. Кириллицу в имени переменной использовать нельзя.

Переходим к следующему уроку.


Массивы, записи и перечисления

На предыдущем уроке мы рассмотрели с вами такую важную вещь, как переменные. А переменные - это ведь кусочки памяти, где хранятся данные. Значит, если эффективно использовать переменные - мы эффективно используем память. А если мы эффективно используем память - то памяти для приложения нужно меньше и приложение работает быстрее. Так вот для того, чтобы эти данные использовать с максимальной эффективностью, и в то же время с лёгкостью, были придуманы "массивы" (Arrays), "записи" (Types) и "перечисления" (Enums).

Массивы

Их ещё называют списками. Итак что же такое массивы? Массив (вектор) - это набор однотипных переменных, объединенных одним именем и доступных через это имя и порядковый номер переменной в наборе. Количество элементов массива теоретически может быть бесконечным, ограничения накладываются конкретными языком программирования и операционной системой. Элементы массива обладают непрерывной нумерацией определённого диапазона.

В программировании массивы используются довольно часто. Например, вам нужно загрузить в программу содержимое какого-нибудь файла. Если этот файл строковый, то можно использовать строку и обойтись без массива. А вот если файл бинарный (двоичный), то тут без массива просто не обойтись!

В Visual Basic массивы определяются следующим образом:

Dim myArray (10) As Long

Как вы могли заметить, определение массива отличается от определения обычной переменной только индексом, указанным в скобках. Этот индекс указывает размерность массива. В данной случае массив myArray будет содержать 11 элементов. Почему 11? Потому что нижняя граница массива начинается с нуля. [0,1,2.....9,10]. Чтобы задать определённую размерность можно использовать зарезервированное слово To:

Dim myArray (5 To 10) As Long

Здесь определяется массив, размерность которого 6 элементов (5,6,7,8,9,10).

Общий синтаксис определения массива следующий:

Dim ИмяМассива{НомПерв1 То НомПосл1, НомПерв2
То НомПосл2, ...) [As [New] ИмяТипа]

Многомерные массивы

Массивы можно делать многомерными. Например, объявим массив - таблицу поля шахматной доски:

Dim chessTable (1 To 8, 1 To 8) As String

Этот массив представляет собой таблицу с восьми ячейками по вертикали и горизонтали.

Итак, массив определён. Теперь необходимо узнать - как же можно добраться к элементам этого массива. Очень просто! К элементам массива нужно обращаться по индексу, к примеру, чтобы изменить нулевой элемент массива myArray нужно написать:

myArray(0) = 1234

Или, например:

chessTable (2,3) = "Пешка"

Массивы переменной размерности (динамические)

Динамические массивы - это такие массивы, размерность которых может меняться в ходе работы программы. Пожалуй динамические массивы используются даже чаще статических. Рассмотрим характерный пример использования такого массива. Пусть у нас есть процедура, которая загружает содержимое двоичного файла в массив. Массив мы можем определить так:

Dim fileContent (119) As Byte

Но это если файл имеет длину 120 байт. А что делать, если мы не знаем длину загружаемого файла? Определять очень большой массив, чтобы уж наверняка туда мог поместиться большой файл? Нет. Так делать нельзя. Вот здесь как раз и нужно использовать динамический массив.

Visual Basic предоставляет довольно мощные средства для работы с такими массивами. Опеределяется такой массив следующим образом:

Dim myArray () As Byte

В отличие от массивов статичных размеров, когда обращаться к элементам можно сразу после его объявления, к элементам динамического массива сразу обращаться нельзя, т.к. они ещё не инициализированы. Для начала нужно указать его новую размерность. Для это в VB есть оператор ReDim. Работает он следующим образом:

ReDim myArray (4)

Теперь массив myArray имеет одну размерность с индексами от 0 до 4 (т.е. всего 5 элементов). Теперь к такому массиву можно обращаться точно так же, как и к статичному. Если в дальнейшем возникнет необходимость снова изменить размерность массива, можно ещё раз использовать ReDim.

Но! Здесь есть подводный камень! Давайте рассмотрим маленький примерчик:

Dim myLong As Long
Dim myArray() As Long ' объявляем массив

ReDim myArray (2) ' одна размерность [0,1,2]
myArray (1) = 234 ' присваиваем второму элементу чило 234
myLong = myArray (1) ' сохраняем его в переменной myLong

ReDim myArray (3) ' снова меняем размерность-теперь [0,1,2,3]
myLong = myArray (1) ' снова пытаемся сохранить второй элемент

На последней строке, переменной myLong присвоится 0 вместо 234! Это происходит потому, что оператор ReDim заново инициализирует (сбрасывает) все элементы массива к значению по умолчанию (как помните, для чисел - это 0, для строк ""). Но как же быть, если мы хотим изменить размеры массива, сохранив все старые элементы? Для этого нужно после оператора ReDim поставить слово Preserve. Примерно так:

ReDim Preserve myArray (3) ' сохраняем старые элементы
myLong = myArray (1) ' всё в порядке

Теперь всё в порядке.

Полезные советы по работе с массивами в VB

Массивы могут храниться в переменных типа Variant. Иногда это бывает удобным. В некоторых случаях без этого просто не обойтись! (Например, когда вы хотите, чтобы ваша функция возвращала массив). Чтобы сохранить какой-либо массив в переменной типа Variant необходимо просто присвоить этой переменной нужный массив:

Dim myVariantArray ' переменная Variant по умолчанию
myVarianrArray = chessTable

Обратите внимание, никакие индексы указывать не нужно!

Теперь можно использовать копию как обычный массив:

myVarianrArray (0) = "Это копия"

Если вам потребуется в коде программы узнать текущие размеры массива, то можно использовать встроенные функции Visual Basic - LBound и UBound. Первая функция возвращает нижнюю границу массива, вторая верхнюю. Подробнее об этих функциях читайте в справочнике (vbhelprus).

Записи

Те, кто программировал на других языках программирования (таких, как C и Pascal), наверняка сталкивались с понятием структура (C), и записью (Record в паскале). В Visual Basic аналогом структуры является запись. Запись - это новый, опеределяемый программистом тип данных, который состоит из одной и более переменных внутри. Давайте рассмотрим это на примере. Например, необходимо в программе хранить массив студентов. Причём каждый студент имеет свои характеристики: ФИО, Возраст, Ниличие Грамот. Конечно, для хранения таких данных можно использовать, например, массив, имеющий две размерности. Но это не лучший вариант. Лучше всего здесь подходят Записи! Затем из записи можно будет сделать массив! Чтобы определить запись в программе нужно использовать зарезервированное слово Type. Заканчивается запись словами End Type:

Private Type Student ' вместо Private могло быть и Public
    FIO As String
    Age As Byte
    HasGramot As Boolean
End Type

Заметьте, что Dim перед именем переменной указывать не нужно. Итак, мы определили запись в программе. Теперь можно объявлять переменные, имеющий тип - Student (т.е. наша новая запись). Например:

Dim newStud As Student

Слово Student синим выделяться не будет, т.к. синию подсветку имеют только зарезервированные слова, встоенные в Visual Basic

Теперь, к полям записи можно обращаться при помощи точки:

newStud.FIO = "Василий Васильевич Пупкин"
newStud.Age = 19
newStud.HasGramot = False

Всё как в паскале. (ну, и почти как в С).

Visual Basic предоставляет возможность не указывать каждый раз имя переменной типа запись, при обращении к её элементам. Это особенно полезно, когда запись имеет много внутренних членов. Для этого есть слово With:

With newStud
    .FIO = "Бабай Бабаевич Бабаев"
    .Age = 20
    .HasGramot = True
End With

Настало время объявить массив элементов типа запись (точнее типа Student):

Dim myStudArray (20) As Student

Здесь мы объявили массив из 21 студента. Теперь можно обращаться к элементам массива точно так же, как мы это делали раньше:

myStudArray(0).FIO = "Билл Гейтс Пупкинович"

Как видите всё гениальное просто! Особенно в Visual Basic! :)

Перечисления

Перечисления тоже довольно важная и нужная штука. В принципе, вы с ними уже встречались. Где? А вспомните, что происходило, когда вы напротив Boolean переменной ставили знак равенства? Правильно, Visual Basic выдавал вам список из двух значений на выбор - True и False. Это и есть перечисление. Другими словами перечисление - это список констант. Перед использованием такого списка его необходимо определить в программе. Например, рассмотрим перечисление оценок, получаямых студентами:

Enum Ocenka
    Neud = 3
    Horosho = 4
    Otlichno = 5
End Enum

Присваивать значения константам внутри Enum не обязательно. Если этого не сделать, то константы будут принимать значения 0,1,2... и т.д.

Теперь можно объявить переменную типа Ocenka:

Dim oc1 As Ocenka

И, если вы теперь попытаетесь присвоить такой переменной значение - Visual Basic выдаст список (Neud, Horosho и Otlichno) из которого вы сможете выбрать нужное значение. Также эти константы можно использовать, например, при проверке условий, т.е. If oc1 = Horosho Then ... Но об условиях позже.

Чтобы закрепить полученные знания, давайте переопределим нашу запись Student на вот какую:

Private Type Student ' вместо Private могло быть и Public
    FIO As String
    Age As Byte
    HasGramot As Boolean
    ikzamenFizika As Ocenka
    ikzamenMatan As Ocenka
End Type

Теперь чтобы присвоить оценку 5 по матанализу студента под номером 3, необходимо написать:

myStudArray(2).ikzamenMatan = Horosho

Теперь, как видите, код очень прозрачен. Такой код гораздо легче для понимания, поэтому прежде чем определять какие-либо данные в своей программе, сначала подумайте, как это лучше реализовать? Может лучше что-то сделать с помощью записей? Или перечислений? И т.д.

Примечание: Те, кто программировал на паскале помнят про множества. Так вот, могу их огорчить, множеств в Visual Basic нет. Но в принципе, никто не мешает вам реализовать их самостоятельно, написав соответствующие функции.

Ну вот и всё. На этом закончим с массивами, записями и перечислениями. Пора переходить к более практичному - выражениям!


Выражения

Итак, с переменными мы разобрались. Теперь займёмся выражениями.

Выражения

Для начала разберёмся с понятием "выражение". В любом языке программирования выражения являются основными кирпичиками, из которых строится программа. Согласно самому точному определению, которое мне попадалось, "выражение" - это "что-то, что содержит значение". За примером далеко ходить не нужно, возьмём пример из предыдущего урока:

b = 234

Здесь мы присваиваем переменной b значение 234. Другими словами "234" - это выражение со значением 234. А теперь, к примеру рассмотрим строчку:

c = b

Здесь переменной c присваивается выражение b. Значение этого выражения -
b = 234. Т.е. другими словами b - выражение, со значением 234. Рассмотрим более сложный пример выражения - функцию. Объявим функцию MyFunc, возвращающую байт 234:

Public
        Function
        MyFunc() As Byte
MyFunc = 234
End Function

А теперь запишем строку:

c = MyFunc()

Как вы уже наверное догадались, выражение здесь - MyFunc(), со значением 234. Т.е. после присвоения переменной c выражения MyFunc(), она будет содержать значение 234. А вот ещё пример:

c = 5 + 5 * 2

Здесь выражение это 5 + 5 * 2. Значение этого выражения не трудно посчитать, оно равно 15 (не 20!). Можно было бы написать и так:

c = MyFunc() - 219

Здесь значение выражение такое же, как и в предыдущем случае, но вот сами выражения разные. Это важно понимать.

Также необходимо отметить значение скобок в выражениях. Помните скобки в школе? Так вот в Visual Basic скобки выполняют ту же функцию, что и в школе, а именно - задают приоритет операции. К примеру, модифицируем выражение 5 + 5 * 2 на:

c = (5 + 5) * 2

Теперь значение этого выражения не 15, а 20! Запомните это.

Идём дальше. Рассмотрим другие, очень распространённые выражения - выражения сравнения. Такие выражения возвращают True или False, в зависимости от получившегося значения выражения. К таким выражениям относятся:

Dim
        bRes As Boolean ' переменная
        для хранения результата
Dim a As Long
Dim b As Byte
Dim c As Long

a = 234 ' переменные для теста
b = 5
c = 1000

bRes = c > b ' 1
bRes = c < b ' 2
bRes = a >= c ' 3
bRes = b <= 4 ' 4
bRes = b <= 5 ' 5
bRes = a <> b ' 6
bRes = Not (a = b) '
        7
bRes = c = MyFunc() ' 8
' и им подобные...

Итак, рассмотрим каждый случай подробно:

  1. Здесь, переменной типа Boolean - bRes присваивается значение выражения (c > b). Т.е. Visual Basic сравнивает эти переменные, и смотрит, c > b? Если да, то значение этого выражения сравнения - True. Если же нет, то False.
  2. То же самое, только bRes будет содержать значение False, т.к. c больше b, а не меньше, как указано в выражении.
  3. Здесь происходит сравнение значений переменных a и c. Т.е. a больше или равно c? В нашем случае a = 234, c = 1000, значит не больше и не равно (меньше). bRes будет содержать False.
  4. b сравнивается с числом 4. Вспомните, ведь 4 - это тоже выражение, со значением 4! Т.к. b > 4, то bRes = False.
  5. Здесь также происходит сравнение переменной b с числом, 5. Но на этот раз одно из условий выполнени, а именно b = 5! Значит bRes = True.
  6. Очевидно, что b <> a. Стало быть bRes должно быть равно True!? Да, так оно и есть... ;)
  7. Обратите внимание на этот пример. После выполнения этой строчки, bRes будет равно True! Здесь выражение Not (a = b) вычисляется следующим образом: сначала Visual Basic сравнивает значения a и b. После того, как VB убедится в том, что a <> b (т.е. False), он вычисляет выражение:
    Not (False). Оператор Not - это булев оператор отрицания. Он инвертирует значение. В данном случае из False получается True. (на более низком уровнем, могу добавить, что оператор Not инвертирует все биты операнда, в данном случае, т.к. False в VB - это 0, а True - FFFF, то значение выражения - True).
  8. Здесь ничего особенно не происходит. bRes = False. Почему? Пусть это будет вашим домашним заданием :).

Ну и последний пример, который иллюстрирует применение выражений сравнения. Сделаем так, чтобы переменной a присвоилось значение 234, если
c = b, и 100, если c <> b:

If c = b Then a = 234
If c <> b Then a = 100

А можно так:

If
      c = b Then
a = 234
End If

If c <> b Then
    a = 100
End If

Оба этих варинта абсолютно эквивалентны, но теряется наглядность. Лучше использовать следующий вариант:

If c = b Then
    a = 234 ' строчка #1
Else
    a = 100 ' строчка #2
End If

Здесь конструкция If выполнит строчку #1 тогда и только тогда, когда c будет равно b. Если же они не будут равны, то выполниться строчка #2. Подробнее всё это мы рассмотрим далее.

Итак, с выражениями, я думаю, мы окончательно разобрались. Теперь, если вы запомнили, что такое константа, переменная и выражение, то можно ехать дальше. К уроку №12.


Операторы

Что такое выражения мы узнали. Настало время вспомнить, что же такое оператор?

Операторы

Здесь опять вспомним школу. Помните простые арифметические операторы? Такие как сложение, деление, вычитание, умножение. В Visual Basic они тоже есть. И их с лёгкостью можно использовать. Давайте рассмотрим пример из предыдущего урока:

c = 5 + 5 * 2

В выражении 5 + 5 * 2 используются 2 оператора: + и *. Их действия очевидны - сложение и умножение. Так же, как и в алгебре, здесь действует принцип приоритетов. Он заключается в том, что каждый оператор имеет свой приоритет. Например, умножение имеет больший приоритет, чем, скажем, сложение. Поэтому результат такого выражения не 20, а 15. Приоритет можно указать явно, поставив в нужной части выражения круглые скобки:

c = (5 + 5) * 2

Теперь результат выражения - 20, т.к. сначала выполнится оператор сложения и только потом умножение.

Помните на предыдущем уроке мы использовали Not, для отрицания . Так вот - Not - это тоже оператор, только не арифметический, а логический.

Операторы бывают разные:

В Visual Basic операторы бывают следующих типов:

  • Арифметические:
    • ^ оператор возведения в степень.
    • * оператор умножения.
    • / оператор деления
    • \ оператор целочисленного деления
    • Mod оператор вычисления остатка от деления
    • + оператор сложения
    • - оператор вычитания
  • Сравнения:
    • < меньше
    • > больше
    • <= меньше или равно
    • >= больше или равно
    • = равно
    • <> не равно
  • Конкатенации:
    • + оператор конкатенации
    • & оператор конкатенации
  • Логические:
    • And оператор логического умножения
    • Eqv оператор логической эквивалентности
    • Imp оператор логической импликации
    • Not оператор логического отрицания
    • Or оператор логического сложения
    • Xor оператор логического исключающего сложения

Как я уже говорил, каждый оператор имеет свой приоритет, и любое выражения вычисляется с учётом этих приоритетов. Для справки, я бы хотел привести очень интересную таблицу приоритетов:

Арифметические | Сравнения | Логические
Возведение в степень(^) | Равно (=) | Not
Отрицание (–) | Неравно (<>) | And
Умножение и деление (*, /) | Меньше чем (<) | Or
Целочисленное деление (\) | Больше чем (>) | Xor
Остаток от деления (Mod) | Меньше или равно (<=) | Eqv
Сложение и вычитание (+,-) | Больше или равно (>=) | Imp
Конкатенация (&) | Удовлетворение маске (Like) |
 | Принадлежность к типу (Is) |

В этой тиблице сверху вниз показан порядок следования приоритетов операторов Visual Basic. Сверху вниз приоритет убывает. Операторы (* и /) имеют одинаковый приоритет, и в выражении вычисляются слева направо. Это же относится к операторам сложения и деления. Если в выражении встречаются операторы из разных категорий, то вычисляются они в порядке столбцов слева направо. Т.е. сначала арифметические, затем операторы сравнения и лишь затем логические операторы.

Подробное описание всех операторов вы можете посмотреть здесь.

Итак, пойдём дальше. Нас ждут управляющие структуры языка Visual Basic.


Управляющие структуры

Этот раздел посвящён операторам, которые предназначены для управления процессом выполнения всех остальных исполняемых операторов Visual Basic. Такие классические структуры, как условные операторы и операторы цикла, имеются во всех процедурных языках программирования, имеются они и в Visual Basic.

Примечание: Здесь бы хотелось заметить, что управляющие структуры мы тоже будем называть операторами. Операторы, рассмотренные на предыдущем уроке используются в выражениях. А операторы рассматриваемые в этом уроке предназначаются для управления вычислением этих выражений (в документациях такие операторы называются - Statement). Важно понимать различие между этими операторами.

Условный оператор If...End If

Этот оператор вы уже встречали в восьмом уроке. Он необходим для принятия решений, нужно ли выполнять то или иное действие или нет. Другими словами если Логическое_выражение истинно, то Оператор выполнится. Если ложно, то выполнение не произойдёт.

If Логическое_выражение Then Оператор

или сложнее

If Логическое_выражение Then
    Группа_операторов
End If

В первом случает оператор может быть только один. Во втором сколько угодно (в том числе и один).

Пример:

If (a = b) And (c <> d) Then
    b = d
    a = 20
End If

Скобки здесь не обязательны, но они повышают читабельность кода.

Условный оператор If...Else...ElseIf...End If

Такая конструкция используется для более сложных ветвлений:

If Логическое_выражение 1 Then
    Группа_операторов
ElseIf Логическое_выражение 2 Then
    Группа_операторов
...
Else
    Группа_операторов
End If

Эта схема может быть и в укороченном виде If...Then...Else...End If. При этом операторы после Else выполняются только в том случае, если ни одно из условий не выполнено.

Пример:

If (a = b) Or (c <> d) Then
    b = d
    a = 20
Else
    c = d
End If

Выражение c=d будет выполнено только в том случае, если a<>b или c=d.

Условный оператор Select Case...End Select

Конструкция Select Case "принимает решение" на основе анализа значения одного выражения. При этот это выражение указывается в строке Select Case:

Select Case Анализируемое_выражение

Case Значение№1
    Группа операторов
Case Значение№2
    Группа операторов
...
Case Значение№N
    Группа операторов
Case Else
    Группа операторов

End Select

Конечно, анализируемое выражение должно возвращать значение типа, совместимого с типом значений в строка Case.

Пример:

В зависимости от значения переменной iTest, строковой переменной strResult присваиваются различные значения

Select Case iTest

Case 1
    strResult = "iTest = 1"
Case 2, 3, 4
    strResult = "iTest = 2, 3 или 4"
Case 5 To 9
    strResult = "iTest находится в диапазоне от 5 до 9"
Case iTest < 0
    strResult = "iTest меньше 0"
Case Is > 9
    strResult = "iTest больше 9"
Case Else
    strResult = "iTest равно 0"

End Select

Оператор цикла For...Next

Этот цикл используют в том случае, когда заранее известно стартовое и конечное значение счётчика. Синтаксис выглядит следующим образом:

For Счётчик_цикла = Старт To Стоп Step Шаг
    Группа операторов
Next [Счётчик_цикла]

Роль счётчика цикла может играть только ранее объявленная переменная целочисленного типа. Шаг задаёт приращение счётчика цикла при каждом проходе. Умолчательно значение шага равно 1. После слова Next счётчик можно опустить.

Пример:

В этом примере всем элементам массива iArray присваивается значение 5.

Dim c As Integer
Dim iArray(10) As Integer
For c = 0 To 10
    iArray(c) = 5
Next c

Оператор цикла For Each...Next

Эта специфическая форма цикла For предназначена для выполнения некоторой операции с каждым объектом, входящим в состав некоторой коллекции объектов (такой операцией, например, может быть вызов метода или присваивание значения свойству). Синтаксис оператора:

For Each ИмяОбъекта In ИмяКоллекции
    Операции над объектами
Next ИмяОбъекта

Пример:

В этом примере показано, как изменить свойство BackColor у всех этикеток (Label), лежащих на форме

Dim x As Object
For Each x In Me.Controls
    If TypeName(x) = "Label" Then
        x.BackColor = 0
    End If
Next x

Me здесь - текущая форма. Т.е. не обязательно использовать полное имя формы для доступа к её свойствам. Например, для закрытия текущей формы, можно написать Me.Hide. (или Unload Me).

Оператор цикла Do While...Loop / Do...Loop While

Эти две разновидности цикла тесно взаимосвязаны, и их часто рассматривают как один из базовых видов цикла. Как уже отмечалось, циклы For применяют в тех случаях, когда количество проходов и диапазон изменения счётчика цикла заранее известны. Циклы While предназначены для ситуаций, когда количество проходов цикла заранее не известно, но зато известно условие выхода из цикла. Синтаксис цикла While:

Do While Условие_выхода
    Группа операторов
Loop

Do
    Группа операторов
Loop While Условие_выхода

Отличие между ними заключается в том, что условие выхода проверяется в одном случае перед очередным проходом, а в другом случае - после выхода. Если в цикле опустить условие выхода или это условие всегда выполняется, то получится бесконечный цикл. Например вот такой

Do While 2 > 1
    Degub.Print "Вечный цикл"
Loop

Если у вас случаянно получился такой цикл, то выйти из него можно при нажатии Ctrl+Break. Но это работает только в среде разработки.

Пример:

Dim n As Integer
n = 100
Do While n >= 0
    n = n - 1
    Debug.Print n
Loop

Оператор цикла Do Until...Loop / Do...Loop Until

По своей логике цикл Until подобен циклу While с той лишь разницей, что проходы цикла выполняются до тех пор, пока условие выхода не выполняется.

Пример:

Dim n As Integer
n = 100
Do
    n = n - 1
    Debug.Print n
Loop Until n < 11

Выход из цикла Exit For / Exit Do

С помощью операторов Exit... можно осуществить досрочный выход из цикла вне зависимости от значения, которое имеет в данный момент условие выхода.

Пример:

Dim n As Integer
n = 10
Do While n > 1
    n = n - 1
    Debug.Print n
    If n = 5 Then Exit Do ' Если счётчик = 5, то
                        'выходим из цикла
Loop

Итак, управляющие структуры - очень важное и далеко не слабое звено в программировании на Visual Basic (да и не только на Visual Basic). Без таких использования таких структур не получится написать даже самую маленькую программу. Даже если и получится, то программа не будет представлять никакого практического интереса.
Но есть ещё более важное звено программы - функция. Вот как раз функциями мы сейчас и займёмся! Рассмотрев функции, мы уже сможем написать какую-нибудь полезную в хозяйстве програмку.


Процедуры и функции

Выражения и операторы - это сырьё для блоков, из которых строится программы, где в роли блоков выступают процедуры и функции.

Процедуры и функции

В Visual Basic, как и во многих других языках программирования, большинство программ создается из блоков - процедур и функций. Весь программный код находится как бы внутри этих процедур. Если возникает необходимость в решении какой-либо задачи в любом месте программы, то вызывается процедура. В Visual Basic нельзя ввести код между процедурами. Код всегда должен находиться внутри процедуры.

Давайте разберёмся с понятиями, и определим, что будет называться процедурой, а что функцией.

Процедуры:

Процедура - это некий блок кода, который будет выполняться всякий раз при вызове этой процедуры. Каждая процедура начинается зарезервированным словом Sub и заканчивается End. Вот общий синтаксис процедуры:

[Private | Public | Friend] [Static] Sub name [(arglist)]
    [здесь некий код]
    [Exit Sub]
    [здесь тоже может быть некий код]
End Sub

Всё, что заключено в квадратные скобки - является необязательным. Оператор Exit Sub позволяет досрочно выйти из процедуры. Иногда это очень удобно. Слова Public, Private имеют то же значение, что и при объявлении переменных.

arglist имеет следующий вид:

[Optional] [ByVal | ByRef] [ParamArray] varname[( )]
[As type] [= defaultvalue]

Рассмотрим пример процедуры, которая будет выводить на экран сообщение "Hello World!":

Private Sub ShowMessage()
    MsgBox "Hello World!"
End Sub

Что можно сказать об этой процедуре? Процедура имеет тип Private, т.е. доступна будет только из кода именно той формы (модуля), где она объявлена (вспомните типы объявления переменных). Данная процедура не содержит параметров, о чём нам говорят пустые круглые скобки.. Назначение - вывести сообщение Hello World на экран.

MsgBox - это встроенная функция Visual Basic, которая выводит на экран окно с сообщением, заданным в качестве параметра. Остальные параметры необязательны (их всего 5). Подробнее о функции MsgBox можно прочитать здесь.

Как вызвать процедуру? Для этого достаточно написать имя процедуры:

ShowMessage

А можно и так:

Call ShowMessage' более наглядные вариант

Оба этих варианта абсолютно эквивалентны. Но для вызова процедур всё-таки лучше использовать второй вариант.

Теперь давайте изменим эту процедуру и добавим к ней параметр, значение которого будет выводиться функцией MsgBox (вместо Hello World):

Private Sub ShowMessage(message As String)
    MsgBox message
End Sub

Теперь при вызове процедуры необходимо указать параметр:

Call ShowMessage ("Наша первая процедура")

Результатом выполнения такой процедуры будет вывод на экран сообщения: "Наша первая процедура". Скобки, окружаемые параметр обязательны, если перед именем процедуры стоит оператор Call. Если Call отсутствует, то скобки ставить не нужно.

Давайте рассмотрим подробнее что же происходит при вызове нашей процедуры. Встретив строку с вызовом нашей процедуры Visual Basic проверяет, нужны ли данной процедуре параметры. Убедившись в том, что нужны (параметр message) он передает в процедуру строку "Наша первая процедура". Т.е. фактически в процедуре происходит присвоение переменной message значения "Наша первая процедура". Ну а далее происходит вызов функции MsgBox и вывод сообщения на экран. Если количество параметров, передаваемых при вызове процедуры не совпадёт с количеством параметров в объявлении процедуры - Visual Basic сгенерирует ошибку.

Итак, с процедурами разобрались. Настало время разобраться с функциями.

Функции:

Функция - это некий блок кода, который будет возвращать значение. Этим, и только этим функции отличаются от процедур. Общий синтаксис функции:

[Public | Private | Friend] [Static] Function имяфункции _
[(arglist)] [As type]
    [здесь некий код]
    [имяфункции = выражение]
    [Exit Function]
    [здесь тоже может быть некий код]
    [имяфункции = выражение]
End Function

Что значит "будет возвращать значение"? Рассмотрим функцию из урока 8:

Public Function MyFunc() As Byte
    MyFunc = 234
End Function

c = MyFunc()

Когда мы говорили о выражениях, мы говорили, что MyFunc - это выражение, со значением 234. Т.е. здесь, функция MyFunc возвращает значение 234 (байт). Чтобы задать это значение, необходимо присвоить имени функции выражение. В нашем случае в качестве выражения выступает число 234.

Давайте рассмотрим более практичный пример. Напишем функцию для вычисления квадрата числа. У функции будет 1 параметр типа Integer - число для возведения в квадрат. Функция будет возвращать значение квадрата параметра. Тип возвращаемого значения - Long:

Public Function Square(number As Long) As Long
    Square = number * number
End Function

Вызвать функцию можно так:

b = Square (5)

А можно так, используя нашу процедуру для вывода сообщения на экран:

ShowMessage Square (5)

А можно и так:

Square 5

В последнем случае возвращённое функций значение уходит в никуда, но сама функция благополучно выполнится. Обратите внимание на отсутствие скобок в последнем вызове. Скобки здесь не обязательны, в отличие от двух предыдущих вызовов. Там скобки обязательны. (ну это и понятно, как бы Visual Basic без скобок догадался, где параметры для ShowMessage, а где для Square).

На следующем уроке мы познакомимся с элементами управления и напишем небольшую программу.


Сводим всё вместе

В этом уроке мы попробуем написать нашу первую программу на Visual Basic - программу для решения квадратных уравнений. Может быть эта программа и не очень полезна в хозяйстве, но она хорошо вас ознакомит с принципами программирования на VB. Итак, приступим. Всмомним из урока 5 основные этапы разработки приложение на Visual Basic:

  1. Продумывание программы
  2. Проектирование интерфейса
  3. Написание программного кода
  4. Отлаживание программы
  5. Окончательная компиляция

Программу будем писать согласно этим пунктам:

1. Продумывание программы.

Что должна делать наша программа? - решать квадратные уравнения. Вспомним, как решаются квадратные уравнения.

a*x*x + b*x + c = 0

Чтобы решить такое уравнение, нужно найти его дискриминант и затем, корни. Дискрименант ищется по формуле:

D = b*b - 4*a*c

А корни:

Если дискриминант > 0, то

X1 = (b + (корень из D)) / 2*a
X2 = (b - (корень из D)) / 2*a

Если дискриминант = 0, то

X1 = X2 = b / 2*a

Если дискриминант < 0, то корней не существует.

Итак, что вышло:

Входные данные в программу - коэффициенты a,b,c. Данные будем вводить в текстовые поля для ввода (TextBox).

Выходные данные - корни (если они есть) и дискриминант. Данные будем выводить в элемент метку (Label). Запускать решение будем нажатием на кнопку (Command Button).

С первым пунктом разобрались. Переходим ко второму - проектирование интерфейса будущей программы.

2. Проектирование интерфейса.

Запустите Visual Basic. Выберите тип Standart EXE. Поместите на форму элементы управления, как показано на рисунке:

Нужные элементы управления выделены красным цветом. Для чего нужны эти элементы? Элемент метка (Label) нужен для отображения текста. Т.е. служит как бы подсказкой. В нём мы будем выводить наш дискрименант и корни. Элемент текстовое поле (TextBox) предназначен для ввода пользователем информации. Введённую информации можно легко получить в коде программы. Для этого у TextBox есть свойство Text. Ну, и наконец, элемент кнопка (CommandButton), нужен для запуска некоторого действия. В нашем случае действием будет решение квадратного уравнения. А запускаться оно будет при нажатии на кнопку.

Разместить элементы управления лучше следующим образом: поместите сначала на форму элемент Label. В окне Properties измените свойство Caption этого элемента на "A:". Затем перетащите на форму элемент TextBox так, чтобы он оказался рядом с элементом Label. Удалите текст из элемента TextBox (свойтво Text). Затем выделите оба этих элемента (используя Ctrl) и скопируйте их в буфер обмена клавишами Ctrl+C. Далее нажмите Ctrl+V. Visual Basic спросит вас, нужно ли создать массив из вставляемых элементов управления? Ответьте Нет. Теперь на форме появилась копия элементов Label и TextBox (для параметра B). Скопируйте таким же образом элементы для параметра C. У кнопки измените свойство Caption на "Решить!". Изменяя свойство Caption кнопки, вы, тем самым изменяете текст на самой кнопке. (Если этого не сделать, то пользователю нашей программы трудно было бы догадаться, что же произойдёт при нажатии на кнопку Command1!?). Обратите внимание на кнопки управления формой (справа вверху). Их 3 штуки: свернуть, развернуть и закрыть. Кнопка развернуть нашей форме совсем не к чему. Давайте её уберём. Для этого выделите форму (щёлкните по ней) и в окне Properties отредактируйте свойство BorderStyle. Вам предложат выбрать несколько значений из списка, а именно:

0-None - у формы не будет заголовка и кнопок управления.
1-Fixed Single - форма будет иметь заголовок и одну кнопку - закрыть.
2-Sizeable - задаётся по умолчанию. Форма имеет все 3 кнопки.
3-Fixed Dialog - то же, что и 1, но форму не будет видно на панели задач
4-Fixed ToolWindow - сокращённый вид заголовка и одна кнопка - закрыть
5-Sizeable ToolWindow - то же что и 4, но можно изменять размеры формы

Укажите 1 номер (Fixed Single). Обратите внимание на кнопки управления - осталась только одна - закрыть форму. Но куда же делась кнопка свернуть? Она могла бы нам пригодиться! Давайте вернём её. Для этого нужно установить свойство формы MinButton в True. Теперь всё ОК.

Ну и последний штрих. Зделаем текст "Результаты решения" подчёркнутым. Для этого выделите Label и найдите в окне Properties свойство Font. Если выделить это свойство, то справа появится маленькая кнопочка, при нажатии на которую откроется окно выбора шрифта. Возможно это окно вы уже где-то видели. Например при выборе шрифта в Блокноте. Дело в том, что это окно - одно из общих диалогов Windows (Common Dialogs). К ним относятся такие окна, как "Открытие файла", "Сохранение файла", "Настройки принтера", "Выбор цвета", "Выбор шрифта", "Выбор каталога", "Поиск и замена текста". такие окна не нужно создавать самому. Их предоставляет Windows. Итак, в окне выбора шрифта поставьте галочку - Подчёркнутый. Нажмите ОК.

Вы уже наверное давно заметили тот факт, что у разных элементов управления некоторые свойства часто повторяются (об этом я говорил на предыдущих уроках). Например свойство Caption, Name или свойство Font. Более того, свойство Name есть у ЛЮБОГО элемента управления. Это связано с объектно ориентированным программированием (ООП). Мы не будем подробно на этом останавливаться, т.к. сейчас это не столь важно. Позже, я постараюсь затронуть эту тему и рассказать про ООП. А пока примите это как факт.

Обратите внимание на имена (свойство Name в окне Properties) только что созданных элементов. Label1, Label2... Text1, Text2.... Command1. При создании нового элемента Visual Basic всегда даёт такие имена сам. В последствии они могут быть изменены. Вообще, имена элементов управления очень важная вещь. Такая же важная, как имена переменных. По этим именам вы будете обращаться к вашим элементам управления в коде программы. Существуют некоторые рекомендации по именованию элементов управления. Всегда придерживайтесь их! Подробнее об этом можно прочитать здесь.

Давайте переименуем элементы управления. Для этого измените свойство Name каждого элемента управления согласно таблице:

Назначение элемента управления | Имя (свойство Name)
A: - параметр A | txtParamA
B: - параметр B | txtParamB
C: - параметр C | txtParamC
Кнопка для запуска решения | cmdCalculate
Label, с вычисленным дискриминантом | lblD
Label, с корнем X1 | lblX1
Label, с корнем X2 | lblX2
Форма, содержащая все эти элементы | frmMain

Остальные элементы переименовывать не обязательно, т.к. мы к ним не будем обращаться в коде программы. Но, если хотите, можете переименовать. Приучайтесь к этому.

Интерфейс готов. Он конечно не претендует на звание самого удобного и красивого интерфейса года ;), но для начала сойдёт. Всё равно, в дальнейшем, уже после написания кода программы, вы сможете изменить интерфейс по вашему вкусу.

3. Написание программного кода.

Теперь самое интересное! Мы будет писать код для нашей программы! Давайте ещё раз продумаем алгоритм работы программы:

  1. Вводим исходные данные в тектовые поля (a,b,c). Напомню, что код для этого писать не нужно. За нас всё сделает Visual Basic и Windows. В этом то и заключается прелесть графического интерфейса пользователя (GUI). Мы только считаем введенные значения и всё.

  2. После нажатия на кнопку, производим вычисление дискриминанта и корней.

  3. Выводим полученные значения в метки (Label'и).

Нам необходимо написать обработчик события клик (Click) нашей кнопки - cmdCalculate. Что значит обработчик события? Обработчик события - это процедура, которая будет выполняться всякий раз, когда произойдёт то или иное событие. Например собите Click. Оно происходит всякий раз при нажатии на кнопку. Т.е., если запустить программу на выполнение и не нажимать на кнопку cmdCalculate ничего не произойдёт. Но как только вы кликните по кнопке, произойдёт выполнение кода, который написан в процедуре обработки события Click (процедуре с именем cmdCalculate_Click). Он будет выполняться всякий раз, когда пользователь кликнет по кнопке. В этом то и состоит та самая Событийно-Управляемая модель программирования, которая отличается от плоских последовательных программ (Turbo Паскаля, например). Программирование на Visual Basic целиком и полностью базируется на этой Событийно-Управяемой модели.

Надеюсь, что вы уловили мою мысль. Если нет, то не отчаивайтесь, далее всё станет понятно.

Чтобы создать обработчик события Click необходимо сделать двойной клик по нашей кнопке cmdCalculate (при двойном клике, VB создаёт заготовку обработчика события - по-умолчанию. У кнопки, это событие Click, у формы - Load, у таймера - Timer и т.д.). Visual Basic создаст для вас заготовку процедуры, которая будет выглядеть следующим образом:

Private Sub cmdCalculate_Click()

End Sub

Чтобы создать обработчик для другого события, необходимо выбрать событие в правом списке в окне кода:

В списке довольно много различных событий. Прочитать о каждом вы можете в здесь. В левом списке вы можете выбрать доступные элементы управления, которые помещены на форму. В данном случае в списке вы видите cmdCalculate. Очень удобно.

Так же, как и некоторое свойства элементов управления, события тоже повторяются. Например, событие Click. Оно есть и у элемента кнопки (Command Button), и у элемента метки (Label) и у многих других. Есть оно и у формы. Это очень облегчает процесс программирования. Не нужно тратить много времени на изучение каждого элемента управления, т.к. многое повторяется.

Заметьте также, что у процедуры обработки события Click нет входных параметров, о чём нам говорят пустые скобки. Добавить свои параметры в эту процедуру нельзя. У процедур обработки некоторых других событий могут быть параметры. Например, у события MouseMove (координаты курсора мыши) или KeyUp (код отжатой клавиши). Эти параметры передаются незаметно для программиста, и их можно использовать по своему усмотрению (а можно и вовсе не использовать).

Теперь давайте приступим непосредственно к программированию. Для начала объявим переменные с типом Double (для хранения вещественных чисел):

Private
        Sub cmdCalculate_Click()
'
        объявляем переменные
Dim paramA As Double
Dim paramB As Double
Dim paramC As Double

Dim x1 As Double
Dim x2 As Double
Dim D As Double
End Sub

Теперь считаем введённые параметры a, b и с. Для этого присвоим переменным paramA, paramB и paramC значения свойства Text всех 3-х полей для ввода (TextBox'ов). Мы можем это сделать потому, что Visual Basic сам преобразует число в виде строки в обычное число с плавающей точкой.

paramA = txtParamA.Text
paramB = txtParamB.Text
paramC = txtParamC.Text

Доступ к свойству любого элемента управления осуществляется через точку, которая разделяет имя свойства и имя элемента. Обратите внимание на технологию Intellisence. Visual Basic выдает список доступных свойств этого элемента управления. Это очень удобно. Вам не придётся выучивать наизусть длинные и сложные названия свойств. Достаточно выбрать нужное свойство из списка и всё.

Теперь нам нужно рассчитать дискриминант. Для этого присвоим переменной D, которая будет хранить значение дискриминанта, следующее выражение:

D = (paramB * paramB) - (4 * paramA * paramC)

Скобки я поставил для наглядности. Ставить их в данном случае не обязательно, т.к. умножение всё равно выполниться до вычитания. (вспомните, что умножение имеет больший приоритет, чем вычитание).

Теперь, зная значение дискриминанта, нужно сравнить его с нулём. Если он больше нуля, то вычислить оба корня, если равен нулю, то вычислить один корень, ну а если меньше, то ничего не вычислять и выдать сообщение о том, что корней нет. Такое ветвление мы организуем с помощью оператора If:

If
        D > 0 Then
x1 = (paramB + Sqr(D)) / (2 * paramA)
x2 = (paramB - Sqr(D)) / (2 * paramA)
lblD.Caption = "Дискременант: " & D
lblX1.Caption = "Корень №1: " & x1
lblX2.Caption = "Корень №2: " & x2
ElseIf D = 0 Then
x1 = paramB / (2 * paramA)
x2 = x1
lblD.Caption = "Дискременант: " & D
lblX1.Caption = "Корень №1: " & x1
lblX2.Caption = "Корень №2 = Корню №1"
ElseIf D < 0 Then
lblD.Caption = "Дискременант: " & D
lblX1.Caption = "Корней нет!"
lblX2.Caption = ""
MsgBox "Дискременант меньше нуля! Корней нет!", vbCritical
End If

Не забывайте про отступы! С ними код намного нагляднее.

Корень мы вычисляем встроенной функцией VB - Sqr (от Square). В выражениях, которые мы присваиваем свойству Caption у меток, мы используем оператор конкатенации (склеивание строк). Им мы склеиваем строку слева от & со строкой справа. Откуда берётся строка справа? Ведь там переменные типа Double!? Как я уже говорил, Visual Basic неявно занимается преобразованием типов. В данном случае перед конкатенацией, числа Double сначала преобразуются в строку.

В принципе, программа уже готова. Давайте проверим её работоспособность. Нажмите кнопку Start. Появится наша форма. Введите значение в поля: a = 3, b = -6, c = 2. Нажмите на кнопку "Решить!". Если вы всё делати правильно, то должны увидеть следующую картину:

Дело в том, что строка для вывода в Label не вписывается в его размеры. Поэтому происходит перенос на следующую строчку. Чтобы этого избежать, закройте программу и установите свойство меток AutoSize в True (Совет: Чтобы не устанавливать это свойство 3 раза для каждой метки, выдели их сразу все 3 и установите свойство.). Свойство AutoSize - подгоняет размер метки так, чтобы текст в свойстве Caption полностью уместился в одну строчку и не переносился на другую. Теперь снова запустите программу, введите те же значения и нажмите на кнопку:

Теперь всё в порядке! Программа работает! Можете поэкперементировать, вводя разные значения коэффициентов.

Но, обратите внимение! Что произойдёт, если мы, не введя значения в поля , нажмём на кнопку? Что тогда присвоиться нашим переменным? Или, что будет, если мы введём нули в качестве коэффициентов? В обоих случаях Visual Basic сгенерирует ошибку. Почему? Ответ на этот вопрос мы разберём на следующем уроке.


Отладка программы

Итак, на предыдущем уроке мы нашли баги (от слова Bug - жук) в нашей программе, т.е. недочёты (ошибки) . От этих багов нужно избавиться. Посмотрим причину возникновения ошибок. Запустите программу. Ничего не вводя в поля нажмите на кнопку. Visual Basic выдаст окно, в котором скажет: "Type mismatch", т.е. ошибка в типах. В окне доступны 3 кнопки:

End - завершить приложение
Debug - показать место возникновения ошибки, чтобы мы смогли от неё избавиться
Help - вызвать справку о возникшей ошибке.

Нажмите Debug. Visual Basic покажет вам причину возникновения ошибки:

Жёлтым цветом выделена строка - причина ошибки. Если навести курсор мыши на имя переменной, то всплывёт подсказка, в которой Visual Basic сообщит нам её значение. Такая возможноть доступка только в режиме Debug. Текущий режим можно узнать из заголовка окна Visual Basic. Например:

в режиме проектировки интерфейса это строка:
Имя_Проекта - Microsoft Visual Basic [design]

при запущенном приложении:
Имя_Проекта - Microsoft Visual Basic [run]

в режиме Debug:
Имя_Проекта - Microsoft Visual Basic [break]

Наведите мышкой на txtParamA.Text. VB сообщит о том, что значение текстового поля txtParamA.Text = "" (пустым кавычкам, или по другому - пустая строка). Здесь можно догадаться, почему происходит ошибка несовпадения типов. Ведь переменная paramA должна хранить вещественное число, а здесь мы пытаемся присвоить ей строковое значение - "". Если бы paramA имела тип String, или в txtParamA.Text была бы строка - число ("123") - ошибка бы не возникла. А здесь Visual Basic просто не может сам конвертировать строку "" в число типа Double. Мы должны найти возможное решение ошибки. Давайте заглянем в раздел vbhelprus. Найдём там функцию Val. О! Это как раз то, что нужно! Давайте изменим код:

paramA = txtParamA.Text
paramB = txtParamB.Text
paramC = txtParamC.Text

На код:

paramA = Val(txtParamA.Text)
paramB = Val(txtParamB.Text)
paramC = Val(txtParamC.Text)

Теперь ошибок несовпадения типов быть не может, т.к. функция Val при любом параметре возвратит число, а сама функция Val никогда не вызовет ошибки, хотя ... но это уже на совести разработчиков VB :)

Проанализируем полученный результат. Что изменилось после того, как мы вставили функцию Val? Теперь мы знаем что переменным paramA, paramB и paramC в любом случае присвоится число. Но вот какое число? Ведь если мы введём в поля нули, то и переменные будут содержать нули! Также, если в поля мы введём !буквы!, то переменные также будут содержать нули. Значит нужно сделать проверку на содержание в переменных нулей. Запустите программу и введите в поля нули (или буквы) и нажмите кнопку. Visual Basic выдаст окно:

Нажимаем Debug и вот что видим:

Причина ошибка заключается в невозможности деления на 0, а paramA у нас как раз и равен 0. К тому при нулевых коэффициентах квадратное уравнение решается гораздо проще (например, если c=0, то x вынесем за скобку, ну а дальше всё просто). Избавимся от этого недоразумения. Для этого, вставим после присвоения значения свойства Text переменным ещё одну проверку - проверку на содержание нулей в переменных:

If paramA = 0 Or paramB = 0 Or paramC = 0 Then
    MsgBox "Нули в качестве коэффициентов не допускаются!", _
    vbCritical
    Exit Sub
End If

Символ "_" используется в том случае, когда вы хотите перенести часть выражения на другую строчку. В данном случае мы переносим константу vbCritical.

Здесь мы проверяем переменные на содержание в них нулей. В принципе, можно было бы проверить не переменные, а сами тектовые поля (If Val(txtParamA.Text)=0 Then....). Это уже дело вкуса. Всё равно, результат одинаков.

Второй баг побеждён! Можно запускать программу и решать уравнения :).

Итоговый код программы:

Private Sub cmdCalculate_Click()

' объявляем переменные
Dim paramA As Double
Dim paramB As Double
Dim paramC As Double

Dim x1 As Double
Dim x2 As Double
Dim D As Double

paramA = Val(txtParamA.Text)
paramB = Val(txtParamB.Text)
paramC = Val(txtParamC.Text)

If paramA = 0 Or paramB = 0 Or paramC = 0 Then
    MsgBox "Нули в качестве коэффициентов не допускаются!", _
    vbCritical
    Exit Sub
End If

D = (paramB * paramB) - (4 * paramA * paramC)

If D > 0 Then
    x1 = (paramB + Sqr(D)) / (2 * paramA)
    x2 = (paramB - Sqr(D)) / (2 * paramA)
    lblD.Caption = "Дискременант: " & D
    lblX1.Caption = "Корень №1: " & x1
    lblX2.Caption = "Корень №2: " & x2
ElseIf D = 0 Then
    x1 = paramB / (2 * paramA)
    x2 = x1
    lblD.Caption = "Дискременант: " & D
    lblX1.Caption = "Корень №1: " & x1
    lblX2.Caption = "Корень №2 = Корню №1"
ElseIf D < 0 Then
    lblD.Caption = "Дискременант: " & D
    lblX1.Caption = "Корней нет!"
    lblX2.Caption = ""
    MsgBox "Дискременант меньше нуля! Корней нет!", vbCritical
End If

End Sub

Может быть вы уже заметили, что при каждом запуске программы, форма появляется всё время в разных местах. Давайте избавимся от этого, и сделаем так, чтобы форма при каждом запуске появлялась в центре экрана. Для этого изменим свойство StartUpPosition в "2-CenterScreen".

Использование пошаговой трассировки:

Пошаговая трассировка - это метод отладки приложения при котором можно выполнять код по одной команде и следить за ходом её выполнения. Это очень полезный метод! Таким методом можно находить те ошибки, которые не может найти Visual Basic. Такие ошибки называются логическими. Здесь я бы хотел привести очень интересный и поучительный отрывок из книги "Программирование в среде Visual Basic 5":

"Прежде чем отлаживать программу, необходимо убедиться в том, что она содержит ошибки. Поэтому тестирование программы является первым шагом на пути её отладки. Одним из способов тестирования программы является её запуск с различными исходными данными и наблюдение за правильностью её функционирования. (чем мы выше и занимались). Этот процесс заканчивается в том случае, когда программа корректно реагирует на все вводимые данные. Однако этот способ не эффективен для больших программ. В любом случае выбор тестовых данных для проверки корректности работы является достаточно важным. Выбор необходимых тестовых данных связан с большими трудностями, так как надо проверить все возможные пути выполнения программы для того, чтобы быть уверенным в отсутствии ошибок."

"Тестирование программ - это больше исскусство, чем наука. Не существует каких-либо правил, которые всегда срабатывают. Если программа имеет большой размер кода или достаточно сложную структуру и нет уверенности в том, что удастся проверить её по всем возможным путям выполнения, то в этом случае вам стоит подойти к процессу тестирования с точки зрения здравого смысла. Например, фирма Microsoft не имеет возможности проверять каждую новую версию ОС на всех возможных конфигурациях аппаратного обеспечения."

"Ключ к успешному тестированию лежит в словосочетании "здравый смысл", и в следующей истории будет показана жизненная важность этой концепции. Одна коммунальная компания использовала достаточно сложную, но, как считалось, надёжную программу для посылки счетов на оплату и приема квитанций. В случае когда компания не получала оплаченной квитанции от пользователя, тот автоматически лишался предоставляемых коммунальных услуг. В тот день, когда произошла эта история, один из клиентов компании, уходя в отпуск, выключил электричество. В результате чего комптьютер послал ему счёт за электричество в размере $0.00, который, естесственно, не мог быть оплачен. После определённого числа запросов на оплату компьютер решил, что тот клиент, которому был послан счет, не уплатил вовремя эти самые $0.00, вследствии чего он остался без электричества!"

"В истории не говорится о реакции разгневанного клиента, однако, если эта история произошла на самом деле, то вина программиста, написавшего приложение, в том, что он забыл вставить проверку на наличие пустых счетов. Видимо он просто не предполагал, что подобная ситуация может возникнуть. (Хотя, по правде говоря, многие программисты используют в операторах сравнения выражение a > b, вместо a >= b)."

"Мораль этой истории такова, что надо для проверки корректности работы программы использовать граничные значения, так как именно такие значения позволяют находить ошибки."

Вот так вот дорогие читатели. Как видите программ без ошибок не бывает. Теперь я думаю вам понятно, почему время от времени приходится переустанавливать Windows :))).

Ну вернёмся к отлаживанию (избавлению программы от лажи ;). На чём мы остановились? Ах да, на пошаговой трассировке и логических ошибках. Вот именно такая логическая ошибка оставила клиента без электричества. Для нахождения этих ошибок очень удобно использовать пошаговую трассировку.

Как использовать такую трассировку? Нужно всего навсего в нужном месте программы поставить точку останова (брикпоинт (Breakpoint)). Дойдя до такого места, Visual Basic преостановит выполнение программы и переведёт вас в режим Debug, где вы сможете выполнять код покомандно. Давайте поставим брикпоинт в нашей программе, и проследим ход её выполнения. Чтобы поставить точку останова нужно кликнуть на вертикали слева от кода:

А можно и по другому. Нажмите правой кнопкой мыши на той строчке кода, где вы хотите поставить брикпоинт и в меню выбрать Toggle->Breakpoint. Замечание: такую точку нельзя ставить на строчке с объявлением переменной.

Поставьте точку как показано на рисунке и запустите программу. Введите следующие данные в качетсве параметров: a = 3, b = -6, c = 2. Нажмите на кнопку "Решить!". Visual Basic остановит выполнение программы точно на той строчке, на которой стоит брикпоинт. Теперь VB в режиме Debug. Вы можете просматривать значения переменных, наводя на них курсор мыши и выполнять программу по шагам. Чтобы выполнить одну команду, нужно нажать F8 или Shift+F8. Отличие этих двух команд заключается в том, что при нажатии F8 на строчке с вызовом процедуры Visual Basic войдёт в эту процедуру и вы сможете продолжить пошаговое выполнение в этой процедуре до строчки End Sub, где VB вернёт вас на то место, где произошёл вызов. Если же нажать Shift+F8, то Visual Basic выполнит процедуру, но не будет заходить в неё для пошаговой трассировки.

Теперь потрассируйте программу. Проследите за тем, как изменяются значения переменных при присвоении им значения. Теперь откройте окно Locals Window. (меню View->Locals Window). В этом окне отображаются значения всех локальных переменных:

Здесь изображены все наши локальные переменные. Их 6 штук. "А вот что такое Me?" - спросите вы. Никак "Millenium"? :) Нет, "Me" - это тоже зарезервированное слово Visual Basic. Оно указывает на текущую форму. В своей программе вы можете обращаться к своей форме через Me. Например, если написать

Me.Hide

То с экрана скроется та форма, в коде которой написан этот код. (простите за каламбур).

Также можно заметить значок "+" слева от "Me". При нажатии на него произойдёт раскрытие списка со всеми дочерними объектами формы. Там же будут находится все элементы управления помещённые на форму, а также все глобальные переменные уровня этой формы.

Заметьте, что окно Locals - плавающее , и при двойном щелчке по заголовку окна оно "пристыкуется" в среду VB. При очередном двойном щелчке окно "отстыкуется".

Дотрассируйте (т.е. пройдите пошагово) программу до конца. Закройте её.

Обработка других ошибок

Независимо от того, насколько качественно написано приложение, никогда нельзя полностью исключать возможность возникновения ошибки в программе. Вы наверняка видели, да нет, точно видели такое окошко Windows: "Программа выполнила недопустимую операцию и будет закрыта...". Т.е. возникла исключительная ситуация, и Windows, не зная как можно обойти ошибку, выдаёт "общее" окно для всех таких ошибок. Так вот и в ваших программах тоже может возникнуть такая исключительная ситуация. Причин для этого ооочень много. Например, у пользователя программой сбои с жёстким диском, или глючит операционная система, или вирус удалил нужный вам файл и т.д. и т.п. В общем, в таких ситуациях желательно сообщить пользователю о том, что возникла ошибка и спокойно выйти/продолжить программу. О том как это сделать и будет рассказано далее.

В Visual Basic существуют несколько глобальных объектов. Это Err, Printer, Screen, Clipboard и App. Эти объекты доступны в любом месте программы. В данном случае нас интересует только объект Err. О назначении и использовании других объектов, возможно, расскажу в статьях.

Объект Err содержит в себе 6 свойств и 2 метода. Этот объект содержит информацию о последней произошедшей ошибке. Вот наиболее важные свойства:

Err.Number
Err.LastDllError

Эти свойства содержат номер последней произошедней ошибки. Первое - содержит номер ошибки самого Visual Basic. Второе - номер ошибки при работе с API функциями. Пока нам понадобится только первое свойство.

Visual Basic располагает оператором, с помощью которого можно контролировать ход программы при возникновении ошибок. Это оператор On Error. Он имеет несколько видов:

On Error GoTo МЕТКА
On Error Resume Next
On Error GoTo 0

Первый оператор позволяет указать Visual Basic метку (номер строки) на которую передастся управление программы при возникновении ошибки. Рассмотрим пример использования этого оператора:

Private Sub Command1_Click()
    Dim myString As String
    On Error GoTo ERRH
    myString = "ERROR HANDLING WITH VB IS COOL"
    MsgBox Mid(myString, 0, 1) '<--- здесь ошибка (#)
    Exit Sub '<--- досрочно выходим, если нет ошибок
ERRH: '<--- метка
    MsgBox Error(Err.Number) '<--- выводим свою ошибку
End Sub

Что здесь произойдёт при выполнении этого кода? Итак, сначала объявляется переменная myString. Затем мы используем оператор On Error.... В качестве метки указываем метку ERRH (Метка в VB - это слово с двоеточием на конце). Т.е. здесь мы указываем VB, что при возникновении ошибки нужно передать управление на метку ERRH. Далее мы присваиваем строке некоторое значение. Пока всё в рамках правил. А вот в строке (#) происходит ошибка, а именно - функция Mid выдаёт ошибку "Invalid procedure call or argument" (Неверные вызов процедуры или аргумент). Это происходит, потому что второй параметр функции Mid меньше единицы. А он должен быть больше или равен ей (так написано в документации). Таким образом, происходит ошибка с номером 5. В нашем обработчике ошибки мы выводим MsgBox с описанием возникшей ошибки. Функция Error имеет один аргумент - номер ошибки. Функция возвращает строку - описание ошибки. Теперь запустите этот код (Для этого поместите на форму кнопку и вставьте этот кусок в код формы). Вы увидите наш MsgBox c ошибкой. Обратите внимание, что этот MsgBox выдаём мы, а не сам Visual Basic, как было бы, если бы не было оператора On Error. Также заметьте оператор Exit Sub, который мы поставили перед меткой ERRH. Как вы помните, этот оператор предназначен для досрочного выхода из процедуры. Он здесь необходим для того, чтобы случайно не выполнился наш обработчик ошибки в том случае, когда ошибки нет. Т.е. если вы измените второй аргумент функции Mid с 0 на 1, убрав таким образом причину ошибки, то вы увидите только MsgBox в строке (#). Код после ERRH выполнятся не будет.

Итак, вывод. Используйте оператор On Error тогда, когда вы не полностью уверены в правильности выполнения того или иного кода. Например, вы можете перед открытием файла поставить On Error с указанием метки, где вы сможете спокойно обработать случай, когда, например, файла нет на диске, или диск не доступен и т.д. Описание кодов ошибок вы можете прочитать здесь.

Необходимо подчеркнуть тот факт, что теперь при возникновении ошибки Visual Basic не выдаёт своё окно с описанием ошибки и нашей любимой кнопкой Debug :). Это можно исправить. Для этого нажмите правой кнопкой в любом месте кода программы и выберите Toggle->Break On All Errors. Теперь Visual Basic всегда будет переводить программу в режим Debug при возникновении любой ошибки (естесственно, это не касается логических ошибок, на них не действует ни один оператор :(.

Давайте теперь посмотрим на оператор Оператор On Error Resume Next. Его можно использовать тогда, когда вы просто хотите подавить ошибку. Т.е. продолжить программу без всяких предупреждений. Замените в нашем примере On Error GoTo ERRH на On Error Resume Next и посмотрите что прозойдёт. Вы не увидите никаких признаков ошибки. Код просто будет продолжен со следующей строчки. В нашем случае - это Exit Sub.

Оператор On Error GoTo 0 удаляет все ранее установленные обработчики ошибок, т.е. разрешает Visual Basic использовать его собственный обработчик ошибок (При возникновении которой, он закроет приложение. А это иногда совсем не к чему).

За более подробной информацией можно обратиться к справочникам.

Переходим к следующему уроку.


Доводим до ума

На этом уроке мы научимся оформлять программу в виде функций и процедур. Это очень важно. Принцип модульного программирования очень облегчает программирование и отладку. Модульное программирование - означает разделение кода программы на отдельные куски, каждый из которых выполняет чётко определённую задачу. Это особенно важно для сложных программ.

Доведём до ума нашу программу, для вычисления корней квадратного уравнения. Как? Очень просто! Давайте оформим некоторые части кода в виде процедур и функций. Например, напишем функцию для вычиления дискриминанта. И напишем процедуру, которая будет выводить полученные значения в метки. Почему именно процедуру? Потому что процедуры пишутся для выполнения некоторой последовательности действий, где не требуется возвращать какое-либо значение. Давайте ещё раз посмотрим на ту часть кода, где происходит проверка значения дискриминанта и вычисление корней уравнения:

If D > 0 Then
    x1 = (paramB + Sqr(D)) / (2 * paramA)
    x2 = (paramB - Sqr(D)) / (2 * paramA)
    lblD.Caption = "Дискременант: " & D
    lblX1.Caption = "Корень №1: " & x1 ' <- здесь
    lblX2.Caption = "Корень №2: " & x2
ElseIf D = 0 Then
    x1 = paramB / (2 * paramA)
    x2 = x1
    lblD.Caption = "Дискременант: " & D
    lblX1.Caption = "Корень №1: " & x1 ' <- и здесь
    lblX2.Caption = "Корень №2 = Корню №1"
ElseIf D < 0 Then
    lblD.Caption = "Дискременант: " & D
    lblX1.Caption = "Корней нет!" ' <- и здесь, тоже
    lblX2.Caption = ""
    MsgBox "Дискременант меньше нуля! Корней нет!", vbCritical
End If

Заметьте, что в каждом из ветвей оператора If наблюдается присвоения свойству Caption 3-х меток (lblD, lblX1, lblX2). Поэтому логично этот участок оформить в виде процедуры, параметрами которой будут значения для меток.

Ну, что ж, приступим?

Сначала напишем функцию для вычисления дискриминанта. Чтобы вычислить дискриминант необходимо знать 3 параметра - коэффициенты a, b и с. Функция будет возвращать значение - дискриминант. Чтобы самому не писать заготовку для этой функции, Visual Basic предоставляет возможность для автоматического создания такой заготовки. Для этого выберите в главном меню VB: Tools->Add Procedure... Появится окно, в котором вас попросят указать вид добавляемой процедуры. Отметьте радиокнопку Function. В поле "Name:", укажите имя добавляемой функции. Давайте назовём её, например, как CalcDiscremenant. Не бойтесь давать длинные названия процедурам и функциям! Всё равно, когда вы захотите использовать эту процедуру в коде, вам не придётся полностью набивать на клавиатуре её имя. Но об этом чуть ниже.

Итак, нажмите OK и Visual Basic создаст для вас следующую заготовку:

Public Function CalcDiscremenant()

End Function

Теперь модифицируем её так, чтобы функция принимала 3 аргумента (параметра) типа Double, и возвращала значение, которое тоже будет иметь тип Double:

Public Function CalcDiscremenant(a As Double, _
b As Double, c As Double) As Double

End Function

Осталось добавить код в нашу заготовку. Сделать это не трудно:

Public Function CalcDiscremenant(a As Double, _
b As Double, c As Double) As Double
    CalcDiscremenant = (b * b) - (4 * a * c)
End Function

Необходимо подчеркнуть, что в Visual Basic параметры можно передавать двумя способами: по значению и по ссылке. Первый способ передает в процедуру (или функцию) только значение передаваемой переменной. Внутри функции изменить значение такой переменной будет нельзя. Второй способ передаёт в функцию ссылку на передаваемую переменную, и её значение легко может быть изменено в теле функции. По умолчанию, Visual Basic всегда передает параметры по ссылке. В нашем случае параметры a, b и c не изменяются внутри функции. Поэтому можно сделать так, чтобы параметры передавались по значению. Для этого перед именем переменной необходимо поставить ключевое слово ByVal (By Value), вот так:

Public Function CalcDiscremenant(ByVal a As Double, _
ByVal b As Double, ByVal c As Double) As Double

В принципе, делать это не обязательно, но всё же желательно. Это повышает наглядность. Теперь, любой, кто воспользуется нашей функцией сразу будет знать, что значения передаваемых переменных внутри функции меняться не будут (да и не могут).

Теперь у нас есть функция, которая будет принимать 3 коэффициента a, b, c и вычислять дискриминант. Давайте опробуем её в действии. Для этого замените в нашей программе строчку, где вычислялся дискриминант:

D = (paramB * paramB) - (4 * paramA * paramC)

на строчку:

D = CalcDiscremenant(paramA, paramB, paramC)

Здесь читатель может возразить - "Как же? Вы же говорили, что имя функции не придётся набирать на клавиатуре!". Так оно и есть! Самый быстрый способ заменить старую строчку на новую такой: (не пользуясь Ctrl+C,Ctrl+V, конечно :) выделите всё, что находится после знака "=". Удалите клавишей Delete. Нажмите Ctrl+J. Visual Basic выдаст вам окно, в котором находятся все доступные на данный момент функции, константы, свойства, перечисления... и т.п., включая пользовательские, т.е. наши ;). Нажмите на клавиатуре всего одну букву "c", и вы увидите нашу, только что созданную функцию!:

Теперь нажмите пробел. Всё! Полное имя функции за вас набрал VB.

Если после имени функции открыть круглую скобку, то Visual Basic для удобства выдаст вам параметры этой функции:

Это очень удобно. Не нужно всегда помнить все параметры всех функций. Достаточно написать имя функции и поставить круглую скобку.

Примечание: Если у вас пропала такая всплывающая подсказка (например, вы кликнули в другом месте кода программа), то вернуть её можно, снова поставив открывающую круглую скобку после имени функции. А можно ещё проще - нажать комбинацию клавиш Ctrl + Shift + I.

Как видите, программировать на Visual Basic очень просто. Причём, эта простота очень хорошо сочетается с богатыми возможностями самого языка. В результате чего, на VB можно легко написать даже очень мощную программу. Конечно, нашу программу мощной не назовёшь, но ведь это только маленький пример возможностей VB! Творите! Всё в ваших руках!

Теперь, можете проверить работоспособность нашей функции. Как видите, всё прекрасно работает.

Осталось написать процедуру для вывода результатов в метки. Добавим затоговку так же, как и в предыдущем случае (Tools->Add Procedure). Только на этот раз не будем отмечать радиокнопку Function, а оставим всё как есть (Sub). В качестве имени процедуры можно ввести, ну, скажем WriteResultsInLabels. Чем длиннее название, тем понятнее, чем занимается данная процедура или функция. Нажмём ОК:

Public Sub WriteResultsInLabels()

End Sub

Сделаем так, чтобы наша процедура принимала 3 параметра - значения, которые необходимо вывести в соответствующие метки:

Public Sub WriteResultsInLabels (lblDCapt As String, _
lblX1Capt As String, lblX2Capt As String)

End Sub

Входные параметры имеют тип String, т.к. передавать в процедуру мы будем именно строки.

Для того, чтобы процедура работала, необходимо добавить в неё код:

Public Sub WriteResultsInLabels (lblDCapt As String, _
lblX1Capt As String, lblX2Capt As String)
    lblD.Caption = lblDCapt
    lblX1.Caption = lblX1Capt
    lblX2.Caption = lblX2Capt
End Sub

Готово. Можно использовать процедуру. Давайте заменим каждые 3 строчки, где мы выводили значения в метки. Получится нечто подобное:

If D > 0 Then
    x1 = (paramB + Sqr(D)) / (2 * paramA)
    x2 = (paramB - Sqr(D)) / (2 * paramA)
    WriteResultsInLabels "Дискременант: " & D, _
    "Корень №1: " & x1, "Корень №2: " & x2
ElseIf D = 0 Then
    x1 = paramB / (2 * paramA)
    x2 = x1
    WriteResultsInLabels "Дискременант: " & D, _
    "Корень №1: " & x1, "Корень №2 = Корню №1"
ElseIf D < 0 Then
    WriteResultsInLabels "Дискременант: " & D, _
    "Корней нет!", ""
    MsgBox "Дискременант меньше нуля! Корней нет!", vbCritical
End If

Программа готова. Конечно можно было бы ещё оформить функцию, для проверки правильности введённых в поля (TextBox) значений. Функцию для вычисления корней уравнения и т.д. Дело ваше. Ведь это был всего лишь вводный курс. Я только хотел показать, как можно использовать возможности Visual Basic на примере простой программки - программки для решения квадратных уравнений. Конечно, многое осталось за кадром. Например, использование других компонентов Visual Basic, таких как Timer, PictureBox и многих других, а также дополнительных OCX компонентов, использование API функций Windows, создание ActiveX компонентов, классов и т.д. и т.п. Всего и не перечислишь. Может быть как-нибудь напишу и об этом. А пока, переходим к последнему уроку - компиляции приложения.

Готовый пример программы для решения квадратных уравнений, созданный в ходе данных уроков можно скачать здесь.


Компиляция

Теперь наша программа отлажена и готова к употреблению. Теперь настало время узнать, как же откомпилировать программу в exe файл?

Напомню, что Visual Basic предлагает 2 компилятора. Компиляция в P-код, и компиляция в Native-код. P-код - это старый компилятор и пользоваться им я не рекомендую. Всегда компилируйте приложение в Native-код. Выбор вида компиляции находится на вкладке Compile в меню Project->Project Properties. Там же можно указать несколько доступных видов оптимизации (о них ниже).

Итак, чтобы откомпилировать нашу программу, необходимо проделать следующие манипуляции:

  1. В меню File выбрать Make имя_проекта.exe
  2. Ввести имя выходного exe файла
  3. Если необходимо, то выбрать некоторые опции, нажав на кнопку Options. (К этим опциям также можно добраться через меню Project->Project Properties).
  4. Нажать ОК. И, если Visual Basic не найдёт никаких ошибок в программе, то откомпилирует её и сохранит в указанно вами каталоге под указанным вами именем.

Теперь можно запустить полученный exe файл и проверить его работоспособность. Теперь вы можете транспортировать его куда хотите, - выкладывать в интернет, принести куда-то и т.д. Единственное, что нужно не забывать, так это то, что для запуска программы необходима библиотека msvbvmX0.dll, которая должна находиться в каталоге Windows\System. X - версия Visual Basic. (5 или 6).

Давайте посмотрим на доступные опции приложения. Откройте окно Project Properties (Project->Project Properties). Откройте вкладку Make:

В рамке Version Number можно указать версию приложения. Посмотреть информацию о версии приложения можно, выбрав вкладку "Версия" в свойствах exe файла. Auto Increment означает автоматическое увеличение версии Revision при каждой компиляции приложения (используя Make).

В рамке Application можно выбрать заголовок приложения (под таким заголовком ваше приложение будет видно в списке задач Window (Ctr+Alt+Del)). Также можно указать иконку для exe файла. В списке можно выбрать доступные формы в приложении. Иконку можно задать с помощью свойства формы "Icon" (вас попросят указать файл, с расширением .ico или .cur).

В рамке Version Information можно указать различную информацию о программе. Посмотреть эту информацию можно будет, выбрав вкладку "Версия" в свойствах exe файла.

Теперь посмотрим, что доступно на вкладке Compile:

Я рекомендую оставлять всё, как есть, так это самый оптимальный вариант. Но если, по каким-то причинам, вас не устраивают стандартный вариант, то можете изменить эти опции, руководствуясь следующей таблицей:

Опция | Описание
Optimize For Fast Code | Максимизирует быстродействие скомпилированных исполняемых файлов, "инструктируя" компилятор, что скорость важнее размера. Когда компилятор транслирует операторы Visual Basic в машинный код, часто имеется выбор среди многих различных последовательностей машинного кода, которые могут правильно представить данный оператор или конструкцию. Иногда эти различия позволяют достичь определенных целей компиляции. Выбор данной опции гарантирует, что, когда компилятор распознает такие варианты, он всегда будет генерировать самую быструю возможную последовательность кодов, даже когда это может увеличивать размер компилированной программы.
Optimize For Small Code | Минимизирует размер скомпилированных исполняемых файлов, инструктируя компилятор, что размер важнее быстродействия. Выбор этой опции гарантирует, что, когда компилятор распознает варианты последовательностей кодов, он всегда будет генерировать наименьшую возможную последовательность, даже когда это может снизить быстродействие выполнения компилированной программы.
No Optimizations | Отключает всякие оптимизации. Если выбрана эта опция, компилятор генерирует код, который будет значительно медленнее и больше по размеру, чем при выборе любого типа оптимизации.
Favor Pentium Pro | Оптимизирует генерацию объектного кода с учетом особенностей архитектуры процессора Pentium Pro (P6). Код, сгенерированный с этой опцией, будет работать также на более ранних процессорах, но менее эффективно. Некоторые стратегии генерации объектного кода, применимые для Pentium Pro, не поддерживаются на компьютерах с процессорами 80386, 80486 и Pentium. Следовательно, использовать эту опцию можно, только если на всех или большинстве машин, выполняющих программу, используется Pentium Pro.
Create Symbolic Debug Info | Генерирует в компилированном исполняемом файле символическую информацию отладки. Программы, компилированные во внутренний код с использованием этой опции, могут быть отлажены в Visual C++ 5.0 или другим совместимым отладчиком. Установка этой опции будет генерировать файл .pdb с требуемой информацией отладки.

И опции в окне Advanced Optimization:

Опция | Описание
Asume No Aliasing | Сообщает компилятору, что программа не использует совмещение имен (псевдонимы). Псевдоним — имя, которое относится к разделу памяти, уже адресуемому другим именем. Псевдонимы используются при передаче параметров ByRef, которые ссылаются на одну переменную. Использование этой опции позволяет компилятору реализовать оптимизации, которые иначе выполнить невозможно, например хранение переменных в регистрах и оптимизации циклов. Однако это может обусловливать неправильное выполнение программы, поэтому, если параметры передаются по ссылке, использовать эту опцию следует осторожно.
Remove Array Bounds Checks | Выключает контроль ошибок допустимых индексов массива и количества размерностей массива. По умолчанию, Visual Basic проводит контроль при каждом обращении к массиву, определяя, находится ли индекс внутри интервала массива. Если индекс вне пределов массива, возвращается ошибка. Выбор этой опции отключает контроль этой ошибки, что может значительно ускорять манипулирование массивами. Однако, если программа обращается к массиву по индексу, который не попадает в пределы размерности, без предупреждений может осуществляться доступ к недостоверным разделам памяти. Это будет обусловливать непредвиденное поведение или сбои программы.
Remove Integer-Overvlow Checks | Отключает вывод ошибок в случаях, когда числовые значения, присваиваемые целым переменным, располагаются вне правильного интервала для типа данных. По умолчанию, Visual Basic выполняет проверку при каждом вычислении с переменной целочисленного типа данных (Byte, Integer, Long и Currency), чтобы гарантировать, что результирующее значение находится внутри требуемого интервала. Если значение имеет неправильную величину, выдается ошибка. Выбор данной опции отключает контроль этой ошибки, что может ускорять целочисленные вычисления. Однако в случае переполнения емкости типа данного ошибка не будет возвращена, и могут иметь место неправильные результаты.
Remove Floating-Point Error Checks | Отключает контроль ошибок, гарантирующий, что числовые значения, присваиваемые переменным с плавающей запятой, находятся в правильном интервале для типов данных и что не будет происходить деление на ноль или другие недопустимые операции. По умолчанию, Visual Basic выполняет проверку при каждом вычислении с переменной типа данных с плавающей запятой (Single и Double), чтобы гарантировать, что результирующее значение находится внутри требуемого интервала. Если значение имеет неправильную величину, выдается ошибка. Выполняется также контроль на недопустимые операции. Выбор данной опции выключает этот контроль, что может ускорять вычисления с плавающей запятой. Однако в этом случае могут иметь место неправильные результаты без индикации ошибок.
Remove Safe Pentium FDIV Checks | Выключает генерацию специального кода, повышающего безопасность деления с плавающей запятой (FDIV — floating-point division) на процессорах Pentium, имеющих ошибку по этой операции. Компилятор внутреннего кода автоматически добавляет дополнительный код для выполнения операции деления с плавающей запятой на процессорах Pentium, которые имеют ошибку FDIV. Выбор этой опции позволяет уменьшить и ускорить код, но в редких случаях может создавать на таких процессорах небольшие погрешности.
Allow Unrounded Floating-point Operations | Позволяет компилятору сравнивать результаты выражений с плавающей запятой без предварительного округления этих результатов к правильной точности. При вычислениях с плавающей запятой перед выполнением сравнения значения обычно округляются к соответствующей степени точности (Single или Double). Выбор этой опции позволяет компилятору, когда это позволяет выполнить операцию более эффективно, производить сравнения с плавающей запятой до округления. Это повышает быстродействие некоторых операций с плавающей запятой. Однако это может привести к тому, что вычисления будут производиться с более высокой точностью, чем ожидается, и два значения с плавающей запятой, которые могли бы считаться равными, не будут таковыми.

С компиляцией проблем возникнуть не должно.

Вот мы с вами и добрались до заключения.


Заключение

Вот мы и подошли к концу этого небольшого курса для начинающих. Я попытался рассмотреть основные принципы программирования на Visual Basic. Пожелания принимаются по адресу: funbit@mail.ru :) Этот курс обучения является финишем сайта "Visual Basic - Крепкий Орешек!". Надеюсь он хоть чем-то вам помог. Сайт пока ещё доступен по адресу: http://vb.hut.ru.

Если у вас возникли трудности или какие-либо вопросы при чтении данного курса - пишите, постараюсь ответить.

Успехов вам в программировании!

Funbit.2003


Стандартные функции и операторы

В этом разделе я решил поместить краткий справочник по функциям и операторам пятого Visual Basic'а. Все описания переводились мной со стандартного Help'а, поставляемого вместе с бэйсиком. Каждое описание сопровождено примером с комментариями.

Навигация разбита по диапазону букв. Если вам, например, нужна функция GetAttr, то ищите её в диапазоне F-G. То же самое и с операторами.

Этот Help поможет тем, у кого VB6 без MSDN, и VB5 без стандартного Help'а. Могу гарантировать, что прочитав весь этот Help, вы будете намного лучше ориентироваться в просторах VB!


Стандартные функции VB (A-C)

Описание ф-ций, встроенных в Visual Basic 5, начинающихся с букв A до C

Список функций, описанных в этом разделе:

  • Abs
  • Array
  • Asc
  • Atn
  • CBool, CByte, CStr, ...
  • Cos
  • Chr
  • Choose
  • Command
  • CreateObject
  • CurDir
  • CVErr

---A---

Abs (number) - возвращает модуль числа.

Пример:

Dim MyNumber
MyNumber = Abs(50.3) ' возвратит 50.3.
MyNumber = Abs(-50.3) ' возвратит 50.3.

Array (arglist) - возвращает переменную типа variant содержащую массив.

Пример:

Dim MyWeek, MyDay
MyWeek = Array("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
' Возвращает значение с нижней границей массива равной 1
MyDay = MyWeek(2) ' Теперь MyDay содержит"Tue".
MyDay = MyWeek(4) ' Теперь MyDay содержит "Thu".

Asc (string) - возвращает код первого символа в строке параметре.

Пример:

Dim
    MyNumber
MyNumber = Asc("A") ' Возвратит 65.
MyNumber = Asc("a") ' Возвратит 97.
MyNumber = Asc("Apple") ' Возвратит 65.

Замечание:

AscB - используется со срокой, длина которой 1 байт

AscW - возвращает двухбайтовый код unicode. (В системах Unix)

Atn (number) - возвращает арктангенс числа.

Пример:

Dim pi
pi = 4 * Atn(1) ' Вычисляет значение числа pi.

---C---

Серия ф-ций конвертирования типов:

CBool (expression) - возвразает boolean значение
CByte (expression) - возвращает значение типа Byte
CCur (expression) - возвращает значение типа Currency
CDate (expression) - возвращает значение типа Date
CDbl (expression) - возвращает значение типа Double
CDec (expression) - возвращает значение типа Decimal
CInt (expression) - возвращает значение типа Integer
CLng (expression) - возвращает значение типа Long
CSng (expression) - возвращает значение типа Single
CVar (expression) - возвращает значение типа Variant
CStr (expression) - возвращает значение типа String

Примеры всех этих ф-ций:

CBool

Dim
    A, B, Check
A = 5: B = 5 ' Инициализация переменных.
Check = CBool(A = B)
    ' Check содержит True.

A = 0 ' Инициализация переменной.
Check = CBool(A) ' Check содержит False.

CByte

Dim
    MyDouble, MyByte
MyDouble = 125.5678 ' MyDouble имеет тип Double.
MyByte = CByte(MyDouble)
    ' MyByte содержит 126.

CCur

Dim
    MyDouble, MyCurr
MyDouble = 543.214588 ' MyDouble имеет тип Double.
MyCurr = CCur(MyDouble * 2)
    ' Конвертирует результат MyDouble * 2

' Double - (1086.429176).
' Currency - (1086.4292).

CDate

Dim MyDate, MyShortDate, MyTime, MyShortTime
MyDate = "February 12, 1969" ' Запись даты в переменную MyDate.
MyShortDate = CDate(MyDate) ' Конвертирование в тип Date.

MyTime = "4:35:47 PM" ' Запись времени в переменную MyTime.
MyShortTime = CDate(MyTime) ' Конвертирование в тип Date.

CDbl

Dim MyCurr, MyDouble
MyCurr = CCur(234.456784) ' MyCurr имеет тип Currency.
MyDouble = CDbl(MyCurr * 8.2 * 0.01) 'Конвертирует результат в Double.

CInt

Dim
    MyDouble, MyInt
MyDouble = 2345.5678 ' MyDouble имеет тип Double.
MyInt = CInt(MyDouble)
    ' MyInt содержит 2346.

CLng

Dim
    MyVal1, MyVal2, MyLong1, MyLong2
MyVal1 = 25427.45: MyVal2 = 25427.55 'MyVal1, MyVal2
    имеют тип Double.
MyLong1 = CLng(MyVal1)
    ' MyLong1 содержит 25427.
MyLong2 = CLng(MyVal2)
    ' MyLong2 содержит 25428.

CSng

Dim
    MyDouble1, MyDouble2, MySingle1, MySingle2
' MyDouble1, MyDouble2 имеют тип Double.
MyDouble1 = 75.3421115: MyDouble2 = 75.3421555
MySingle1 = CSng(MyDouble1)
    ' MySingle1 содержит 75.34211.
MySingle2 = CSng(MyDouble2)
    ' MySingle2 содержит 75.34216.

CStr

Dim
    MyDouble, MyString
MyDouble = 437.324 ' MyDouble имеет тип Double.
MyString = CStr(MyDouble)
    ' MyString содержит "437.324".

CVar

Dim MyInt, MyVar
MyInt = 4534 ' MyInt имеет тип Integer.
MyVar = CVar(MyInt & "000") 'MyVar содержит значение String "4534000".

Cos (number) - вычисляет косинус числа.

Пример:

Dim MyAngle, MySecant
MyAngle = 1.3 ' Устанавливаем угол в радианах.
MySecant = 1 / Cos(MyAngle) ' Вычисляем секонс.

Chr (charcode) - возвращает символ, соответствующий определённому коду. Эта ф-ция является обратной Asc.

Пример:

Dim
    MyChar
MyChar = Chr(65) ' Возвратит A.
MyChar = Chr(97) ' Возвратит a.
MyChar = Chr(62) ' Возвратит >.
MyChar = Chr(37) ' Возвратит %.

Choose (index, choice-1[, choice-2, ... [, choice-n]]) - выбирает значение из списка аргументов.

Пример:

Function GetChoice(Ind As Integer)
GetChoice = Choose(Ind, "Speedy", "United", "Federal")
End Function

Замечание:

Можно ускорить код с использованием Choose:
Вы можете использовать Choose там, где можно заменить массив или построить таблицы результатов, на стадии компиляции (compile-time), вместо того, чтобы делать это на стадии выполнения (run time). Например, если Вам надо знать значения факториалов чисел от 1 до 10, попробуйте следующий пример (Choose производит выбор факториала из набора имеющихся значений всесто того, чтобы высчитывать факториал каждый раз заново):

Function Factorial (number As Integer) As Long
Factorial = Choose(number, 1, 2, 6, _
24, 120, 720, 5040, 40320, _
362880, 3628800)
End Function

Command - возвращает аргументы с командной строки (т.е. если запустить программу из командной строки, например: myprogram.exe arguments)

Пример:

Этот пример использует функцию Command для получения аргументов с командной строки. Функция GetCommandLine возвратит значение типа Variant содержащее их массив.

Function GetCommandLine(Optional MaxArgs)

Dim C, CmdLine, CmdLnLen, InArg, I, NumArgs
If IsMissing(MaxArgs) Then MaxArgs = 10
'Приводим массив в корректный размер
ReDim ArgArray(MaxArgs)
NumArgs = 0: InArg = False
'Получаем аргументы с командной строки.
CmdLine = Command()
CmdLnLen = Len(CmdLine)
'Перемещаемся по всем символам в командной строке
For I = 1 To CmdLnLen
C = Mid(CmdLine, I, 1)

'Тестируем на пробел или символ табуляции.
If (C <> " " And C <> vbTab) Then
'Если ни то и ни другое.
'Тест на текущий аргумент.
If Not InArg Then
'Новый аргумент начался.
'Тестируем на слишком большое кол-во аргументов.
If NumArgs = MaxArgs Then Exit For
NumArgs = NumArgs + 1
InArg = True
End If
'Соединение символа с текущим аргументом.
ArgArray(NumArgs) = ArgArray(NumArgs) & C
Else
'Ищем пробел или символ табуляции.
InArg = False
End If
Next I
ReDim Preserve ArgArray(NumArgs)
'Возвращаем массив как результат ф-ции.
GetCommandLine = ArgArray()

End Function

CreateObject (class) - возвращает ссылку на объект ActiveX класса class

Пример:

Dim xlApp As Object ' Объявляем переменную типа Object.

Set xlApp = CreateObject("excel.application")
' Должны изменить свойство Visible в True, если хотите,
' чтобы проект Excel был виден
xlApp.Visible = True
' Используем xlApp для доступа к другим объектам Microsoft Excel's.
xlApp.Quit ' Когда вы закончили, используйте
' Quit метод для закрытия Excel
Set xlApp = Nothing ' Сбрасываем ссылку

CurDir [(drive)] - возвращает String, содержащий текущий путь

Пример:

' Предположим,
    что текущим путь на диске C - "C:\WINDOWS\SYSTEM".
' Предположим, что текущим путь на диске D - "D:\EXCEL".
' Предположим, что текущий диск - диск C.
Dim MyPath
MyPath = CurDir ' возвратит "C:\WINDOWS\SYSTEM".
MyPath = CurDir("C") ' возвратит "C:\WINDOWS\SYSTEM".
MyPath = CurDir("D") ' возвратит "D:\EXCEL".

CVErr (error number) - возвращает Variant субтипа Error, содержащий код ошибки, определённый пользователем.

Пример:

' Вызывает
    CalculateDouble с аргументом, приводящим к ошибке.
Sub Test()
Debug.Print CalculateDouble("345.45robert")
End Sub

' Определение
    ф-ции CalculateDouble.
Function CalculateDouble(Number)
If IsNumeric(Number) Then
CalculateDouble = Number * 2 ' Возвращает результат.
Else
CalculateDouble = CVErr(2001)
    ' Возвращает номер ошибки,
' определённый пользователем.
End If
End Function


Стандартные функции VB (D-E)

Описание ф-ций, встроенных в Visual Basic 5, начинающихся с букв D до E

Список функций, описанных в этом разделе:

  • Date
  • DateAdd
  • DateDiff
  • DatePart
  • DateSerial
  • DateValue
  • Day
  • Dir
  • DoEvents
  • Environ
  • EOF
  • Error
  • Exp

---D---

Date - возвращает текущую дату.

Пример:

Dim MyDate
MyDate = Date ' MyDate содержит текущую системную дату.

DateAdd (interval, number, date) - Возвращает дату, в которой к date добавляет временной интервал.

Параметр interval может принимать следующие значения:

yyyy - Год
q - Квартал
m - Месяц
y - День года
d - День
w - День недели
ww - Неделя
h - Час
n - Минута
s - Секунда

number - количество интервалов, которые вы хотите добавить.

Пример:

Dim FirstDate As Date
Dim IntervalType As String
Dim Number As Integer

IntervalType = "m"
'"m" устанавливает в качестве интервала - месяцы.
FirstDate = Date
Number = InputBox("Введите кол-во месяцев для добавки")
MsgBox = "Новая дата: " & _
DateAdd(IntervalType, Number, FirstDate)

DateDiff (interval, date1, date2[, firstdayofweek[, firstweekofyear]]) - возвращает разность между двумя датами. Параметр interval указывает в каком формате будет вычисляться разность (значения такие же, как и ф-ции DateAdd).

Пример:

Dim TheDate As Date
Dim Msg
TheDate = InputBox("Введите дату")
Msg = "Кол-во дней до сегодняшней даты: " & _
DateDiff("d", Now, TheDate)
MsgBox Msg

DatePart (interval, date[,firstdayofweek[, firstweekofyear]]) - Возвращает часть даты (например, месяц или день).

Пример:

Dim TheDate As Date
Dim Msg
TheDate = Date
Msg = "Номер месяца: " & DatePart("m", TheDate)
MsgBox Msg

DateSerial (year, month, day) - Возвратит дату, указанную по частям.

Пример:

Dim MyDate
MyDate = DateSerial (2003, 2, 12)
' Возвратит дату February 12, 2003.

DateValue (string) - Возвращает дату, заданную в виде строки.

Пример:

Dim MyDate
MyDate = DateValue("February 12, 1969") ' Возвратит дату

Day (date) - Возвратит день из указанной даты.

Пример:

'Допустим на дворе 5 апреля 2001г.
Dim MyDate, MyDay
MyDate = Date
'MyDate содержит текущую системную дату(5 апреля 2001г.)
MyDay = Day(MyDate) ' MyDay содержит текущий день (т.е. 5).

Dir [(pathname[, attributes])] - Возвращает строку, содержащую имя файла или директории, которое совпадает с определённой маской, атрибутом или меткой диска.

Пример:

Dim MyFile, MyPath, MyName
MyFile = Dir("C:\WINDOWS\WIN.INI")
' Возвратит "WIN.INI" если файл существует.

MyFile = Dir("C:\WINDOWS\*.INI")
' Возвратит имя файла с расширением INI.
' Если файлов несколько, то возвратится имя первого файла.

' Снова вызываем ф-цию Dir, только без параметров,
' чтобы получить имя следующего файла
' с расширением INI в директории WINDOWS
MyFile = Dir

' Возвратит имя первого файла
' с расширением TXT и атрибутом "скрытый"
MyFile = Dir("*.TXT", vbHidden)

' Нижеприведённый кусок кода
' отобразит в окне Immediate список папок
' в корневой директории на диске С

MyPath = "C:\"
MyName = Dir(MyPath, vbDirectory)
' Возвратит первую директорию.
Do While MyName <> "" ' Начало цикла
' Игнорируем текущую директорию или заключительную
If MyName <> "." And MyName <> ".." Then
' Используем битовое сравнение, чтобы определить
' что MyName есть директория (а не файл).
If (GetAttr(MyPath & MyName) And vbDirectory) = vbDirectory Then
Debug.Print MyName ' Отобразим в окне Immediate MyName
End If
End If
MyName = Dir.
Loop

DoEvents ( ) - Даёт ОС реагировать на события, когда происходят длительные вычисления.

Пример:

Do
Loop
' Попробуйте подвигать форму (что, не получилось? ;)

Do
DoEvents
Loop
' А теперь? Вот так вот.

---E---

Environ ({envstring | number}) - Возвращает строку, ассоциированную с переменной окружения ОС.

Пример:

Form1.Caption = Environ ("WINDIR")
' Возвратит путь к директории Windows

' В этом примере в Text1 отобразятся все
' переменные окружения (по строчкам)
Dim c As String
For a = 1 To 20
c = Environ(a)
If c <> "" Then
Text1.Text = Text1.Text & c & vbCrLf
Else
Exit For
End If
Next a

EOF (filenumber) - Возвращает True, если достигнут конец файла при чтении.

Пример:

Dim InputData
Open "MYFILE" For Input As #1 ' Открываем файл для чтения
Do While Not EOF(1) 'Проверяем не конец ли
Line Input #1, InputData ' Считываем строку
Debug.Print InputData ' Выводим её в Immediate окно
Loop
Close #1 ' Закрываем файл

Error [(errornumber)] - Возвращает строку, содержащую описание ошибки, определённой параметром errornumber.

Пример:

Dim ErrorNumber
For ErrorNumber = 61 To 64
' Выведет описание ошибок с 61 по 64
Debug.Print Error(ErrorNumber)
Next ErrorNumber

Exp (number) - Возвращает экспоненту числа number.

Пример:

Form1.Caption = Exp(1)
'Отобразит на Caption число e (т.е. e в степени 1).


Стандартные функции VB (F-G)

Описание ф-ций, встроенных в Visual Basic 5, начинающихся с букв F до G

Список функций, описанных в этом разделе:

  • FileAttr
  • FileDateTime
  • FileLen
  • Fix
  • Format
  • FreeFile
  • GetAllSettings
  • GetAttr
  • GetAutoServerSettings
  • GetObject
  • GetSetting

---F---

FileAttr(filenumber, returntype) - Возвращает вид открытия файла ф-цией Open. returntype должно равняться 1. Варианты возвращаемых значений (слева - тип, справа - значение):

Input 1
Output 2
Random 4
Append 8
Binary 32

Пример:

Dim FileNum, Mode
FileNum = 1
Open "TESTFILE" For Append As FileNum
Mode = FileAttr(FileNum, 1) ' Возвратит 8 (Т.е. файл открыт
' методом Append).
Close FileNum ' Close file.

FileDateTime(pathname) - возвращает тип Date, даты последнего изменения файла.

Пример:

Dim MyStamp
' Предположим, что файл TESTFILE последний раз был изменён
' 12 февраля 1993 в 16:35:47
MyStamp = FileDateTime("TESTFILE") ' Возвратит "2/12/93 4:35:47 PM".

FileLen(pathname) - возвращает размер файла.

Пример:

Dim MySize
MySize = FileLen("TESTFILE") ' Возвратит длину файла в байтах

Fix(number) - возвратит целую часть числа.

Пример:

Dim
          MyNumber

MyNumber = Fix(99.2) ' возвратит 99.
MyNumber = Fix(-99.8) ' возвратит -99.
MyNumber = Fix(-99.2) ' возвратит -99.

Format(expression[, format[, firstdayofweek[, firstweekofyear]]]) - возвращает String отформатированной строки (как в С).

Пример:

Dim MyTime, MyDate, MyStr
MyTime = #17:04:23#
MyDate = #January 27, 1993#

' Возвратит текущее системное время в длинном формате.
MyStr = Format(Time, "Long Time")

' Возвратит текущую системную дату в длинном формате.
MyStr = Format(Date, "Long Date")

MyStr = Format(MyTime, "h:m:s") ' Возвратит "17:4:23".
MyStr = Format(MyTime, "hh:mm:ss AMPM") ' Возвратит "05:04:23 PM".

MyStr
          = Format(MyDate, "dddd, mmm d yyyy")
' Возвратит "Wednesday,
' Jan 27 1993".

' Если формат не задан, то возвратится просто строка.
MyStr = Format(23) ' Возвратит "23".

' Форматы определённые пользователем

MyStr = Format(5459.4, "##,##0.00") ' Возвратит "5,459.40".
MyStr = Format(334.9, "###0.00") ' Возвратит "334.90".
MyStr = Format(5, "0.00%") ' Возвратит "500.00%".

MyStr = Format("HELLO", "<") ' Возвратит "hello".
MyStr = Format("This is it", ">") ' Возвратит "THIS IS IT".

Если вам нужно подробное описание всех возможных форматов - обращайтесь к документации по VB.

FreeFile[(rangenumber)] - возвратит следующий пустой файловый номер.

Пример:

Dim MyIndex, FileNumber
For MyIndex = 1 To 5 ' Начало цикла
FileNumber = FreeFile ' Получаем неиспользуемый номер
Open "TEST" & MyIndex For Output As #FileNumber
Write #FileNumber, "Это пример." ' Запишем текст в файл
Close #FileNumber ' Закроем файл
Next MyIndex

---G---

GetAllSettings(appname, section) - Возвратит список всех настроек в секции. (Которые были записаны ф-цией SaveSetting).

Пример:

Dim MySettings As Variant, intSettings As Integer
' Запишем кое-какие настройки
SaveSetting "MyApp", "Startup", "Left", 50
' Возвратит строку:
MySettings = GetAllSettings("MyApp", "Startup")
For intSettings = LBound(MySettings, 1) To UBound(MySettings, 1)
Debug.Print MySettings(intSettings, 0), MySettings(intSettings, 1)
Next intSettings
DeleteSetting "MyApp", "Startup" ' Удалим записанные настройки

GetAttr(pathname) - Возвратит атрибуты файла или папки.

Варианты возвращаемых значений:

vbNormal - 0 - Normal
vbReadOnly - 1 - Read-only
vbHidden - 2 - Hidden
vbSystem - 4 - System
vbDirectory - 16 - Directory or folder
vbArchive - 32 - File has changed since last backup

Пример:

Dim MyAttr
' Предположим файл TESTFILE имеет атрибут "скрытый"
MyAttr = GetAttr("TESTFILE") ' Возвратит 2

' Возвратит не ноль, если атрибут "скрытый" установлен
Debug.Print MyAttr And vbHidden

' Возвратит не ноль, если установлены "скрытый" и "только для чтения"
Debug.Print MyAttr And (vbHidden + vbReadOnly)

' Предположим что MYDIR папка.
MyAttr = GetAttr("MYDIR") ' Возвратит 16.

object.GetAutoServerSettings([progid], [clsid]) - с помощью этой ф-ции можно получить ProgID и CLSID, т.е. GUID компонента ActiveX.

Пример:

В этом примере мы получаем информацию о регистрации объекта Hello.

Dim oRegClass As New RegClass
Dim vRC As Variant
vRC = oRegClass.GetAutoServerSettings ("HelloProj.HelloClass")
If Not(IsEmpty(vRC)) Then
If vRC(1) Then
MsgBox "Hello удалённо зарегистрирован на сервере - " & vRC(1)
Else
MsgBox "Hello зарегистрирован локально."
End If
End if

GetObject([pathname] [, class]) - возвращает ссылку на объект ActiveX ассоциированного с определённым файлом.

Пример:

В это примере переменная MyXL получает ссылку на объект ActiveX Excel.

Dim MyXL As Object
Set MyXL = GetObject("C:\Мои документы\EXCEL\Русское лото.xls")
MyXL.Application.Visible = True
MyXL.Parent.Windows(1).Visible = True

'здесь производятся необходимые манипуляции с файлом

MyXL.Application.Quit ' Закрытие приложения Excel
Set MyXL = Nothing ' Освобождение ссылки

GetSetting(appname, section, key[, default]) - Возвращает настройку из реестра, записанную туда ф-цией SaveSetting. Я почему-то не нашёл в документации путь, куда сохраняются настройки. Пришлось определять самому. Оказалось, что настройки записываются по адресу:
HKEY_CURRENT_USER\SOFTWARE\VB and VBA Program Settings

Пример:

Dim znachenie As Long
znachenie = 1212 ' Это число взято от балды, для примера
SaveSetting "MyApp", "Sekcia", "Kluch", znachenie 'сохраняем настройки
Form1.Caption = GetSetting("MyApp", "Sekcia", "Kluch", 2222)
' получаем 1212 или если настроек нет, то
' получаем значение по умолчанию 2222.


Стандартные функции VB (H-I)

Описание ф-ций, встроенных в Visual Basic 5, начинающихся с букв H до I

Список функций, описанных в этом разделе:

  • Hex
  • Hour
  • IIf
  • Input
  • InputBox
  • InStr
  • Int
  • IsArray, IsDate, IsEmpty, ...

---H---

Hex (number) - возвращает строку, содержащую шестнадцатиричное значение числа параметра.

Пример:

Dim
    MyHex
MyHex = Hex(5) ' Возвратит 5.
MyHex = Hex(10) ' Возвратит A.
MyHex = Hex(459) ' Возвратит 1CB.

Hour (time) - возвращает количество часов из параметра типа Time.

Пример:

Dim MyTime, MyHour
MyTime = #4:35:17 PM# ' Присваиваем время
MyHour = Hour(MyTime) ' MyHour содержит 16.

IIf (expr, truepart, falsepart) - возвращает одну из 2-х строк, которая совпадёт с выражением условия. Практически аналог оператора ? в C и Java.

Пример:

В этом примере ф-ция CheckIt возвратит строку "Large", если TestMe > 1000, в противном случае возвратит "Small".

Function CheckIt (TestMe As Integer)
CheckIt = IIf(TestMe > 1000, "Large", "Small")
End Function

Input (number, [#]filenumber) - используется для работы с файлами. Считывает одну компоненту файла.

Пример:

После запуска такой программы в окошке Immediate вы увидите символы, содержащиеся в файле TESTFILE. Ф-ция EOF возвращает True если достигнут конец файла при чтении.

Dim MyChar
Open "TESTFILE" For Input As #1
Do While Not EOF(1) 'Запускаем цикл до тех пор,
' пока не будет достигнут конец файла...
MyChar = Input(1, #1) 'Получаем один символ
Debug.Print MyChar ' Печатаем в окно Immediate
Loop
Close #1 'Закрываем файл

InputBox (prompt[, title] [, default] [, xpos] [, ypos] [, helpfile, context]) - выводит окно с запросом на ввод значения. Параметры такие же, как и у функции MsgBox.

Пример:

Выводим окно с заголовком "ВНИМАНИЕ", запросом "Введите пароль", в окошке будет выделенный текст "Значение_по_умолчанию". Координаты появления окна - 100,100pix.

Form1.Caption = InputBox("Введите пароль", _
"ВНИМАНИЕ", "Значение_по_умолчанию", 100, 100)

InStr ([start, ]string1, string2[, compare]) - возвращает номер позиции первого вхождения строки string2 в строку string1.

Пример:

Dim SearchString, SearchChar, MyPos
SearchString ="XXpXXpXXPXXP" ' Строка, в которой будем искать
SearchChar = "P" ' Строка для поиска

' Текстовое сравнение начиная с 4-ой позиции. Возвратит 6.
MyPos = Instr(4, SearchString, SearchChar, 1)

' Бинарное сравнение начиная с 1-ой позиции. Возвратит 9.
MyPos = Instr(1, SearchString, SearchChar, 0)

' Бинарное по умолчанию. Последний параметр опущен. Возвратит 9.
MyPos = Instr(SearchString, SearchChar)

' Возвратит 0, т.е. строка не найдена.
MyPos = Instr(1, SearchString, "W")

Int (number) - Если number < 0, то округляет его до ближайшего целого. Иначе выделяет целую часть number.

Пример:

Dim MyNumber
MyNumber = Int(99.8) ' Возвратит 99.
MyNumber = Int(-99.8) ' Возвратит -100.
MyNumber = Int(-99.2) ' Возвратит -100.

Следующие функции используются для проверки принадлежность значения к определённому типу данных.

IsArray(varname) - Возвратит True, если varname (имя переменной) является массивом. Иначе False. Переменная может быть и типом Variant. Пример, я думаю, здесь не нужен.

IsDate(expression) - если expression - дата, то возвратит True, иначе False.

IsEmpty(expression) - если переменная пуста (т.е. либо ей присвоено значение Empty, либо значение ещё не задано после объявления переменной) то возвратит True, иначе False.

IsError(expression) - Возвратит True, если переменная содержит ошибочные данные.

Пример:

Dim ReturnVal, MyCheck
ReturnVal = UserFunction()
MyCheck = IsError(ReturnVal) ' возвратит True.

IsMissing(argname) - Возвратит True, если аргументы не заданы. Здесь нужен пример:

Dim ReturnValue
'В следующих строках вызывается процедура, определённая пользователем
ReturnValue = ReturnTwice() ' Возвратит Null.
ReturnValue = ReturnTwice(2) ' Возвратит 4.

' Определение функции, вызываемой выше
Function ReturnTwice(Optional A)
If IsMissing(A) Then
' Если аргументы пропущены, возвратит Null.
ReturnTwice = Null
Else
' Если аргумент задан, то возвратит квадрат этого аргумента
ReturnTwice = A * 2
End If
End Function

IsNull(expression) - немного отличается от IsEmpty. А именно тем, что возвратит False, если переменной ещё не присвоено значение после определения. Пример:

Dim MyVar, MyCheck
MyCheck = IsNull(MyVar) ' Возвратит False.

MyVar = ""
MyCheck = IsNull(MyVar) ' Возвратит False.

MyVar = Null
MyCheck = IsNull(MyVar) ' Возвратит True.

IsNumeric(expression) - Возвращает True, если expression является числовым значением.

Пример:

Dim MyVar, MyCheck
MyVar = "53" ' Задаём значение
MyCheck = IsNumeric(MyVar) ' Возвратит True.

MyVar = "459.95" ' Задаём значение
MyCheck = IsNumeric(MyVar) ' Возвратит True.

MyVar = "45 Help" ' Задаём значение
MyCheck = IsNumeric(MyVar) ' Возвратит False.

IsObject(identifier) - Возвращает True, если переменная объектного типа. Пример:

Dim MyInt As Integer, YourObject, MyCheck
Dim MyObject As Object
Set YourObject = MyObject ' Задаём ссылку на объект
MyCheck = IsObject(YourObject) ' Возвратит True.
MyCheck = IsObject(MyInt) ' Возвратит False.


Стандартные функции VB (L-M)

Описание ф-ций, встроенных в Visual Basic 5, начинающихся с букв L до M

Список функций, описанных в этом разделе:

  • LBound
  • LCase
  • Left
  • Len
  • LoadPicture
  • Loc
  • LOF
  • Log
  • LTrim
  • Mid
  • Minute
  • Month
  • MsgBox

---L---

LBound(arrayname[, dimension]) - возвращает минимально возможую границу размерности массива в заданном заданном измерении.

Пример:

Dim Lower
Dim MyArray(1 To 10, 5 To 15, 10 To 20) 'Объявляем массивы
Dim AnyArray(10)

Lower = Lbound(MyArray, 1) ' Возвратит 1.
Lower = Lbound(MyArray, 3) ' Возвратит 10.
Lower = Lbound(AnyArray) ' Возвратит 0 или 1, в зависимости от
' установленной настройки Option Base.

LCase(string) - переводит строку в нижний регистр.

Пример:

Dim UpperCase, LowerCase
Uppercase = "Hello World 1234" ' Строка для конвертирования
Lowercase = Lcase(UpperCase) ' Возвратит строку "hello world 1234".

Left(string, length) - Возвращает часть строки, начиная с первого символа до указанного номера.

Пример:

Dim AnyString, MyStr
AnyString = "Hello World" ' Определяем строку
MyStr = Left(AnyString, 1) ' Возвратит "H".
MyStr = Left(AnyString, 7) ' Возвратит "Hello W".
MyStr = Left(AnyString, 20) ' Возвратит "Hello World".

Len(string | varname) - Возвращает длину строки string или количество байт, занимаемых переменной varname.

Пример:

Type CustomerRecord ' Определяем свою запись
ID As Integer ' Кладём это определение в модуль
Name As String * 10
Address As String * 30
End Type

Dim
    Customer As CustomerRecord
Dim MyInt As Integer, MyCur As Currency
Dim MyString, MyLen

MyString = "Hello World" ' Инициализация переменной
MyLen = Len(MyInt) ' Возвратит 2.(кол-во байт, занимаемых
    переменной)
MyLen = Len(Customer) ' Возвратит 42.
MyLen = Len(MyString) ' Возвратит 11. (длину строки)
MyLen = Len(MyCur) ' Возвратит 8.

LoadPicture([stringexpression]) - Загружает картинку в переменную типа Picture или элементы PictureBox и Image.

Пример:

Private Sub Form_Click ()

Dim Msg As String
On Error Resume Next ' Устанавливаем обработку ошибки
Height = 3990
Width = 4890 ' Устанавливаем высоту и ширину в твипах
Set Picture = LoadPicture("PAPER.BMP") ' Загрузка картинки
If Err Then
Msg = "Не могу найти .BMP файл."
MsgBox Msg ' Отобразим ошибку
Exit Sub ' Выходим, если ошибка имела место
End If
Msg = "Нажмите ОК для очистки формы от картинки."
MsgBox Msg
Set Picture = LoadPicture() ' Очищаем форму от картинки.

End Sub

Loc(filenumber) - возвращает номер текущей позиции в файле, открытом binary методом.

Пример:

Dim MyLocation, MyLine
Open "TESTFILE" For Binary As #1 ' Открываем существующий файл
Do While MyLocation < LOF(1) ' Зацикливаемся пока не конец файла
MyLine = MyLine & Input(1, #1) ' Читаем символ в переменную
MyLocation = Loc(1) ' Получаем текущую позицию в файле
' и выводим её в окно Immediate
Debug.Print MyLine; Tab; MyLocation
Loop
Close #1 ' Закрываем файл

LOF(filenumber) - Возвратит размер файла в байтах, открытого оператором Open.

Пример:

Dim FileLength
Open "TESTFILE" For Input As #1 ' Открываем файл
FileLength = LOF(1) ' Получаем длину файла
Close #1 ' Закрываем файл

Log(number) - вычисляет натуральный логарифм числа number. (Возвращает тип Double).

Пример:

Dim
    MyAngle, MyLog
' Устанавливаем угол в радианах
MyAngle = 1.3
' Вычисляем обратный гиперболический синус
MyLog = Log(MyAngle + Sqr(MyAngle * MyAngle + 1))

Ф-ция Log вычисляет натуральный логарифм (т.е. по основанию e). Для того, чтобы получить логарифм по основанию n нужно произвести следующее вычисление:

Logn(x) = Log(x) / Log(n)

LTrim(string) - Возвратит строку без лидирующих пробелов.

Пример:

Dim MyString, TrimString
MyString = " <Trim> " ' Устанавливаем строку,
' у которой слева и справа по одному пробелу
TrimString = LTrim(MyString) ' Получили строку "<-Trim-> "
' (т.е. без пробела слева)

---M---

Mid(string, start[, length]) - Возвращает строку, извлечённую из строки string, начиная с символа в позиции start, и содержащую length символов.

Пример:

Dim MyString, FirstWord, LastWord, MidWords
MyString = "Mid Function Demo" ' Создаём текстовую строку
FirstWord = Mid(MyString, 1, 3) ' Возвратит строку "Mid".
LastWord = Mid(MyString, 14, 4) ' Возвратит строку "Demo".
MidWords = Mid(MyString, 5) ' Возвратит строку "Function Demo".

Minute(time) - Возвратит число минут (от 0 до 59) содержащимся в параметре Time. В примере всё яснее.

Пример:

Dim MyTime, MyMinute
MyTime = #4:35:17 PM# ' Присваиваем время
MyMinute = Minute(MyTime) ' MyMinute содержит 35.

Month(date) - то же, что и выше, только возвратит число дней в параметре date.

Пример:

Dim MyDate, MyMonth
MyDate = #February 12, 1969# ' Присваиваем дату
MyMonth = Month(MyDate) ' MyMonth содержит 2.

MsgBox(prompt[, buttons] [, title] [, helpfile, context]) - Выводит на экран окно сообщения (Message Box) которое будет ждать клика на одной из кнопок. Возвращает число Integer, по которому можно определить какую кнопку нажал пользователь.

Пример:

Этот пример выводит на экран критическую ошибку с кнопками Yes и No.

Dim Msg, Style, Title, Response, MyString
Msg = "Do you want to continue ?" ' Устанавливаем текст сообщения
Style = vbYesNo + vbCritical + vbDefaultButton2 ' Устанавливаем стиль
Title = "MsgBox Demonstration" ' Устаналиваем заголовок (Caption).

Response = MsgBox(Msg, Style, Title)
If Response = vbYes Then
MyString = "Yes"
' Выполняем какие-то действия, если пользователь выбрал Yes
Else
MyString = "No"
' Выполняем какие-то действия, если пользователь выбрал No
End If


Стандартные функции VB (N-R)

Описание ф-ций, встроенных в Visual Basic 5, начинающихся с букв N до R

Список функций, описанных в этом разделе:

  • Now
  • Oct
  • QBColor
  • RGB
  • Right
  • Rnd
  • RTrim

---N---

Now - Возвращает Variant значение, содержащее текущие системные дату и время.

Пример:

Dim Today
Today = Now ' Today содержит текущие дату и время.

---O---

Oct(number) - Возвращает восьмиричное значение числа number.

Пример:

Dim
    MyOct
MyOct = Oct(4) ' Возвратит 4.
MyOct = Oct(8) ' Возвратит 10.
MyOct = Oct(459) ' Возвратит 713.

---Q---

QBColor(color) - Возвращает значение Long, содержащее цвет, заданный номером от 0 до 15. Ниже приведена таблица цветов:

Номер | Цвет | Номер | Цвет
0 | Чёрный | 8 | Серый
1 | Синий | 9 | Светло-синий
2 | Зелёный | 10 | Светло-зелёный
3 | Циан | 11 | Светлый циан
4 | Красный | 12 | Светло-красный
5 | Мажента | 13 | Светлая мажента
6 | Жёлтый | 14 | Светло-жёлтый
7 | Белый | 15 | Ярко-белый

Пример:

MyForm.BackColor = QBColor(6)

---R---

RGB(red, green, blue) - Возвращает Long, содержащее цвет, заданный тремя компонентами R, G и B.

Пример:

MyForm.BackColor = RGB(255,0,0) 'цвет формы изменится на красный
MyForm.BackColor = RGB(255,255,255) 'цвет формы изменится на белый

Right(string, length) - возвращает length символов из строки string, начиная справа.

Пример:

Dim AnyString, MyStr
AnyString = "Hello World" ' Определяем строку
MyStr = Right(AnyString, 1) ' Возвратит "d".
MyStr = Right(AnyString, 6) ' Возвратит " World".
MyStr = Right(AnyString, 20) ' Возвратит "Hello World".

Rnd[(number)] - Возвращает Single значение, содержащее случайное число от 0 до 1.

Пример:

Dim MyValue
MyValue = Int((6 * Rnd) + 1) ' Генерирует случайное число от 1 до 6

RTrim(string) - Удаляет пробелы справа от строки.

Пример:

Dim MyString, TrimString
MyString = " <-Trim-> "
'Строка, у которой слева и справа по одному пробелу
TrimString = RTrim(MyString)
'Справа пробела нет, т.е. теперь TrimString = " <-Trim->"


Стандартные функции VB (S)

Описание ф-ций, встроенных в Visual Basic 5, начинающихся с буквы S

Список функций, описанных в этом разделе:

  • Second
  • Seek
  • Sgn
  • Shell
  • Sin
  • Space
  • Spc
  • Sqr
  • Str
  • StrComp
  • StrConv
  • String
  • Switch

---S---

Second(time) - Возвратит количество секунд, содержащихся в параметре time.

Пример:

Dim MyTime, MySecond
MyTime = #4:35:17 PM# ' Присваиваем время.
MySecond = Second(MyTime) ' MySecond содержит 17.

Seek(filenumber) - Возвращает Long, содержащее текущую read/write позицию в файле, открытом оператором Open.

Пример:

' Определение типа должно находится в стандартном модуле

Type Record ' Тип, определённый пользователем
ID As Integer
Name As String * 20
End Type

Dim MyRecord As Record ' Объявляем переменные
Open "TESTFILE" For Random As #1 Len = Len(MyRecord)
Do While Not EOF(1) ' Повторяем, пока не конец файла
Get #1, , MyRecord ' Читаем следующую запись
Debug.Print Seek(1) ' Выводим в окно Debug текущий номер записи.
Loop
Close #1 ' Закрываем файл

Sgn(number) - Возвращает знак числа number.

Пример:

Dim
    MyVar1, MyVar2, MyVar3, MySign
MyVar1 = 12
MyVar2 = -2.4
MyVar3 = 0
MySign = Sgn(MyVar1) ' Возвратит 1.
MySign = Sgn(MyVar2) ' Возвратит -1.
MySign = Sgn(MyVar3) ' Возвратит 0.

Shell(pathname[,windowstyle]) - Запускает программу и возвращает ID программной задачи (program task ID). Если была ошибка, возвратит 0. Параметр windowstyle определяет стиль открытия программы. Может принимать следующие значения:

vbHide Окно будет скрыто
vbNormalFocus Окно получает фокус и отображается без искажений размера
vbMinimizedFocus Окно, после запуска автоматически минимизируется и получает фокус
vbMaximizedFocus Окно разворачивается на весь экран и получает фокус
vbNormalNoFocus Тоже, что и vbNormalFocus, но окно не получает фокуса.
vbMinimizedNoFocus Тоже, что и vbMinimizedFocus, но окно не получает фокуса.

Пример:

Dim RetVal
RetVal = Shell("C:\WINDOWS\CALC.EXE", 1) ' Запускаем калькулятор

Sin(number) - Возвращает Double значение, содержащее синус числа number.

Пример:

Dim MyAngle, MyCosecant
MyAngle = 1.3 ' Определяем угол в радианах
MyCosecant = 1 / Sin(MyAngle) ' Вычисляем косеконс

Space(number) - Возвращает строку, состоящую из number пробелов.

Пример:

Dim MyString

' MyString содержит 10 пробелов.
MyString = Space(10)

' Вставляем 10 пробелов между двумя строками
MyString = "Hello" & Space(10) & "World"

Spc(n) - Используется вместе с оператором Print # или Print для задания отступа.

Пример:

Open "TESTFILE" For Output As #1 ' Открываем файл для записи
Print #1, "10 пробелов между этим местом"; Spc(10); "и этим."
Close #1 ' Закрываем файл

или

Debug.Print Spc(30); "Перед этой строкой 30 пробелов..."

Sqr(number) - Возвращает корень числа number.

Пример:

Dim MySqr
MySqr = Sqr(4) 'Возвратит 2.
MySqr = Sqr(23) 'Возвратит 4.79583152331272.
MySqr = Sqr(0) 'Возвратит 0.
MySqr = Sqr(-4) 'Генерирует ошибку (корень из отрицательного числа).

Str(number) - Возвращает строку, представляющую число.

Пример:

Dim
    MyString
MyString = Str(459) ' Возвратит "459".
MyString = Str(-459.65) ' Возвратит "-459.65".
MyString = Str(459.001) ' Возвратит "459.001".

StrComp(string1, string2[, compare]) - Сравнивает две строки. Возвращает:

-1, если string1 < string2
0, если string1 = string2
1, если string > string2
Null, если string1 или string2 содержит Null.

Параметр compare определяет тип сравнения. Может быть одним из следующих значений:

vbBinaryCompare - по умолчанию, бинарное сравнение
vbTextCompare - сравнивает строки без учёта регистра
vbDatabaseCompare - используется в базах данных Microsoft Access.

Пример:

Dim
    MyStr1, MyStr2, MyComp
MyStr1 = "ABCD"
MyStr2 = "abcd"
MyComp = StrComp(MyStr1, MyStr2, 1) ' Возвратит 0.
MyComp = StrComp(MyStr1, MyStr2, 0) ' Возвратит -1.
MyComp = StrComp(MyStr2, MyStr1) ' Возвратит 1.

StrConv(string, conversion) - Конвертирует строку в формат, заданный параметром conversion. Этот параметр может принимать одно из следующих значений:

vbUpperCase - Конвертирует строку в верхний регистр
vbLowerCase - Конвертирует строку в нижний регистр
vbProperCase - Конвертирует первую букву каждого слова в верхний регистр
vbUnicode - Конвертирует строку в формат Unicode, используя кодовую страницу, заданную в системе.
vbFromUnicode - Конвертирует строку из формата Unicode в нормальный формат, используя кодовую страницу, заданную в системе.

Пример:

MyForm.Caption = StrConv("visual BASIC", vbUpperCase)
' сконвертирует строку в верхний регистр

String(number, character) - Возвращает строку, состоящую из number числа символов character.

Пример:

Dim
    MyString
MyString = String(5, "*") ' Возвратит "*****".
MyString = String(5, 42) ' Возвратит "*****".
MyString = String(10, "ABC") ' Возвратит "AAAAAAAAAA".

Switch(expr-1, value-1[, expr-2, value-2 … [, expr-n,value-n]]) - Возвращает первое значение, условие которого выполняется.

expr-1, expr-2, ... - условия.
value-1, value-2, ... - значения.

Пример:

Функция MatchUp возвратит строку "Italian", если CityName будет равно "Rome",
или строку "English", если CityName будет равно "London" и т.д.

Function MatchUp (CityName As String)
Matchup = Switch(CityName = "London", "English", CityName _
= "Rome", "Italian", CityName = "Paris", "French")
End Function


Стандартные функции VB (T)

Описание ф-ций, встроенных в Visual Basic 5, начинающихся с буквы T

Список функций, описанных в этом разделе:

  • Tab
  • Tan
  • Time
  • Timer
  • TimeSerial
  • TimeValue
  • Trim
  • TypeName

---T---

Tab[(n)] - Используется вместе с оператором Print # или Print для задания отступа.

Пример:

Debug.Print Tab(10); "10 columns from start."

Tan(number) - Возвращает тангенс числа number.

Пример:

Dim MyAngle, MyCotangent
MyAngle = 1.3 ' Устанавливаем угол в радианах
MyCotangent = 1 / Tan(MyAngle) ' Вычисляем котангенс

Time - Возвращает Variant значение, содержащее текущее системное время.

Пример:

Dim MyTime
MyTime = Time ' Возвращает текущее системное время.

Timer - Возвращает Single, содержащее количество секунд, прошедших после полуночи.

Пример:

Dim PauseTime, Start, Finish, TotalTime

If (MsgBox("Нажмите Yes для паузы в 5 сек.", 4)) = vbYes Then
PauseTime = 5 ' Устанавливаем длину паузы
Start = Timer ' Устанавливаем начальное время
Do While Timer < Start + PauseTime
DoEvents ' Обрабатываем другие процессы
Loop
Finish = Timer ' Устанавливаем конечное время
TotalTime = Finish - Start ' Вычисляем общее время
MsgBox "Пауза в " & TotalTime & " секунд."
Else
End
End If

TimeSerial(hour, minute, second) - Возвратит время, указанное по частям.

Пример:

Dim MyTime
MyTime = TimeSerial(16, 35, 17) 'MyTime содержит время 4:35:17 PM.

TimeValue(time) - Возвращает время, заданное строкой.

Пример:

Dim MyTime
MyTime = TimeValue("4:35:17 PM") ' MyTime содержит время 16:35:17

Trim(string) - Удаляет лидирующие и замыкающие пробелы в строке string. Т.е. одновременно выполняет 2 ф-ции: RTrim и LTrim.

Пример:

Dim MyString, TrimString
MyString = " <-Trim-> " ' Строка с обоих сторон содержит 1 пробел

TrimString = Trim(MyString) ' TrimString = "<-Trim->"

TypeName(varname) - Предоставляет информацию о переменной varname.

Пример:

Dim NullVar, MyType, StrVar As String, _
IntVar As Integer, CurVar As Currency
Dim ArrayVar (1 To 5) As Integer

NullVar = Null ' Присваиваем значение Null.
MyType = TypeName(StrVar) ' Возвратит "String".
MyType = TypeName(IntVar) ' Возвратит "Integer".
MyType = TypeName(CurVar) ' Возвратит "Currency".
MyType = TypeName(NullVar) ' Возвратит "Null".
MyType = TypeName(ArrayVar) ' Возвратит "Integer()".
MyType = TypeName(Label1) ' Возвратит "Label"


Стандартные функции VB (U-Y)

Описание ф-ций, встроенных в Visual Basic 5, начинающихся с букв U-Y

Список функций, описанных в этом разделе:

  • UBound
  • UCase
  • Val
  • VarType
  • Weekday
  • Year

---U---

UBound(arrayname[, dimension]) - Возвращает число Long, содержащее максимально возможный индекс массива arrayname указанной размерности. Если вам не всё понятно, то смотрите пример.

Пример:

Dim Upper
Dim MyArray(1 To 10, 5 To 15, 10 To 20) ' Объявляем массивы
Dim AnyArray(10)
Upper = UBound(MyArray, 1) ' Возвратит 10.
Upper = UBound(MyArray, 3) ' Возвратит 20.
Upper = UBound(AnyArray) ' Возвратит 10.

UCase(string) - Переводит строку в верхний регистр.

Пример:

Dim LowerCase, UpperCase
LowerCase = "Hello World 1234" ' Строка для конвертирования
UpperCase = UCase(LowerCase) ' Возвратит "HELLO WORLD 1234".

---V---

Val(string) - Превращает строку в число.

Пример:

Dim MyValue
MyValue = Val("2457") ' Возвратит 2457.
MyValue = Val(" 2 45 7") ' Возвратит 2457.
MyValue = Val("24 and 57") ' Возвратит 24.

MyValue = Val ("") ' Возвратит 0.
MyValue = Val ("laja") ' Возвратит 0.

VarType(varname) - Возвращает тип переменной varname. Возможные значения функции:

vbEmpty - Empty (Не инициализирована)
vbNull - Null (нет правильного значения)
vbInteger - Integer
vbLong - Long integer
vbSingle - Single
vbDouble - Double
vbCurrency - Currency
vbDate - Date значение
vbString - String
vbObject - Object
vbError - значение Error
vbBoolean - Boolean значение
vbVariant - Variant (используется только для Variant массивов)
vbDataObject - Объект доступа к данным
vbDecimal - десятичное число
vbByte - Byte
vbArray - массив

Пример:

Dim IntVar, StrVar, DateVar, MyCheck

IntVar =
    459
StrVar = "Hello World"
DateVar = #2/12/69#
MyCheck = VarType(IntVar) ' Возвратит 2.
MyCheck = VarType(DateVar) ' Возвратит 7.
MyCheck = VarType(StrVar) ' Возвратит 8.

---W---

Weekday(date, [firstdayofweek]) - Возвращает день недели, которому соответствует указанная дата. Возможные значения фунции:

vbUseSystem = 0 Использует в качестве первого дня недели день, используемый
    в системе. (В Америке неделя начинается с Воскресенья, поэтому по умолчанию
    firstdayofweek = 1).
vbSunday = 1 Воскресенье
vbMonday = 2 Понедельник
vbTuesday = 3 Вторник
vbWednesday = 4 Среда
vbThursday = 5 Четверг
vbFriday = 6 Пятница
vbSaturday = 7 Суббота

Пример:

Dim MyDate, MyWeekDay
MyDate = Date ' Присваиваем текущую дату
MyWeekDay = Weekday(MyDate, 0)
' MyWeekDay содержит сегодняшний день недели. Можете проверить :)

---Y---

Year(date) - Возвращает количество годов, содержащихся в параметре date.

Пример:

Dim MyDate, MyYear
MyDate = #February 12, 1969# ' Присваиваем дату
MyYear = Year(MyDate) ' MyYear содержит 1969.


Операторы VB (A-C)

Описание операторов, встроенных в Visual Basic 5, начинающихся с букв A-C

Список операторов, описанных в этом разделе:

  • AppActivate
  • Beep
  • Call
  • ChDir
  • ChDrive
  • Close
  • Const

---A---

AppActivate title[, wait] - Активизирует окно приложения с заголовком title. Вместо заголовка можен быть использовано ID задачи, полученное при помощи функции Shell.

Пример:

Dim MyAppID, ReturnValue
AppActivate "Microsoft Word" 'Активизируется Microsoft Word

MyAppID = Shell("C:\WORD\WINWORD.EXE", 1) ' Запускаем Microsoft Word.
AppActivate MyAppID 'Активизируется Microsoft Word

---B---

Beep - Проигрывает звук, установленный в системе как "Стандартный звук" (в панели управления->Звук). Если такой не установлен, то играется PC спикер.

Пример:

Beep

---C---

[Call] name [argumentlist] - Вызывает процедуру или функцию. Оператор Call может быть опущен.

Пример:

Call PrintToDebugWindow ("Hello World")
'Вызываем процедуру. Скобки обязательны!
PrintToDebugWindow "Hello World"
'То же самое. Скобки можно опустить.

Sub PrintToDebugWindow (AnyString)
Debug.Print AnyString ' Печатаем в окно Debug.
End Sub

ChDir path - Смена текущего каталога.

Пример:

' Изменяем текущую директорию на "MYDIR".
ChDir "MYDIR"

' Пусть диск "С:" является текущим диском. Следующий оператор
' изменяет текущий каталог на "D:\WINDOWS\SYSTEM", но
' текущим диском по-прежнему остаётся "С:".
ChDir "D:\WINDOWS\SYSTEM"

ChDrive drive - Смена текущего диска.

Пример:

ChDrive "D"

Close [number] - Закрывает файл, открытый оператором Open под номером number.

Пример:

Open "TESTFILE" For Output As #3
Print #3, "Hello World"
Close #3

[Public | Private] Const constname [As type] = expression - Объявляет константу.

Пример:

' Константа типа Private (используется по умолчанию).
Const MyVar = 459

' Константа типа Public.
Public Const MyString = "HELP"

' Константа Private, типа Integer.
Private Const MyInt As Integer = 5


Операторы VB (D-E)

Описание операторов, встроенных в Visual Basic 5, начинающихся с букв D-E

Список операторов, описанных в этом разделе:

  • Date
  • Declare
  • DefBool, DefByte, DefInt ...
  • DeleteSetting
  • Dim
  • Do...Loop
  • End Function, End If ...
  • Enum
  • Erase
  • Error
  • Event
  • Exit For, Exit Function ...

---D---

Date = date - изменяет системную дату.

Пример:

Dim MyDate
MyDate = #February 12, 1985# ' Присваиваем дату переменной
Date = MyDate ' Изменяем системную дату

[Public | Private] Declare Sub name Lib "libname" [Alias "aliasname"] [([arglist])] или

[Public | Private] Declare Function name Lib "libname" _
[Alias "aliasname"] [([arglist])] [As type]

Этот оператор имеет 2 синтаксиса. Первый объявляет процедуру, находящуюся в DLL библиотеке (которая объявлена в ней как export). Второй объявляет функцию. Подробнее об объявлениях внешних функций здесь. Замечание: если вы объявляете функцию в разделе формы или компонента ActiveX, то она должна быть объявлена как Private, если в модуле, то Public.

Пример:

' Это находится в модуле:
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) _
As Long

' А это в разделе формы:
GetWindowText Form1.Hwnd, strCapt, 255
' Теперь переменная strCapt создержит заголовок окна Form1

DefBool letterrange[, letterrange] . . .
DefByte letterrange[, letterrange] . . .
DefInt letterrange[, letterrange] . . .
DefLng letterrange[, letterrange] . . .
DefCur letterrange[, letterrange] . . .
DefSng letterrange[, letterrange] . . .
DefDbl letterrange[, letterrange] . . .
DefDec letterrange[, letterrange] . . .
DefDate letterrange[, letterrange] . . .
DefStr letterrange[, letterrange] . . .
DefObj letterrange[, letterrange] . . .
DefVar letterrange[, letterrange] . . .

С помощью этих операторов можно установить тип переменных по умолчанию. letterrange - диапазон символов, с которых должны начинаться имена переменных. Операторы должны находиться в разделе модуля.

Пример:

DefInt A-K
' Переменные, имена которых начинаются с букв L до K будут
' по умолчанию объявлены как Integer. А от L до Z - как String.
' Напомню, что пример работает при выключенном Option Explicit.
DefStr L-Z
CalcVar = 4 ' Объявляется как Integer.
StringVar = "Hello there" ' Объявляется как String.

DeleteSetting appname, section[, key] - удаляет ранее записанную настройку из реестра. Напомню, что функция SaveSetting сохраняет настройку, а функция GetSetting загружает. Я почему-то не нашёл в документации путь, куда сохраняются настройки. Пришлось определять самому. Оказалось, что настройки записываются по адресу:
HKEY_CURRENT_USER\SOFTWARE\VB and VBA Program Settings
В этом ключе создаётся ещё один ключ с названием appname.

Пример:

' Записываем что-нибудь, в нашем случае - это положение окна
SaveSetting "MyApp", "Startup", "Top", Form1.Top
SaveSetting "MyApp", "Startup", "Left", Form1.Left
' Удаляем только что записанные настройки
DeleteSetting "MyApp", "Startup"

Dim [WithEvents] varname[([subscripts])] [As [New] type] [, [WithEvents] _
varname[([subscripts])] [As [New] type]] . . .

Этот оператор используется для объявления переменных. Конструкция, надо сказать, не маленькая. Но в принципе ничего сложного. См пример.

Пример:

' AnyValue и MyValue объявляются как Variant по умолчанию
' и им присваивается начальное значение Empty.
Dim AnyValue, MyValue

' Объявляем перенную типа Integer
Dim Number As Integer

' Здесь объявление происходит в одной строчке. Переменная AnotherVar
' объявляется как Variant, т.к. её тип опущен.
Dim AnotherVar, Choice As Boolean, BirthDate As Date

' DayArray - массив, состоящий из 51-го элемента (от 0 до 50).
' Если в модуле написать Option Base 1, то индексы всех массивов будут
' начинаться с единицы. По умолчанию Option Base установлен в 0
Dim DayArray(50)

' Матрица 4 на 5.
Dim Matrix(3, 4) As Integer

' BirthDay - массив, с индексами от 1 до 10.
Dim BirthDay(1 To 10) As Date

' MyArray - динамический массив типа Variant.
Dim MyArray()

Do...Loop - см. сюда.

---E---

End
End Function
End If
End Property
End Select
End Sub
End Type
End With

Заканчивает процедуру или блок.

End - немедленно завершает выполнение программы. Закрывает все открытые файлы и очищает все переменные.
End Function - необходим для завершения функции.
End If - необходим для завершение проверки условия оператором If.
End Property - необходим для завершения процедур Property Let, Property Get или Property Set.
End Select - необходим для завершения оператора Select Case.
End Sub - необходим для завершения процедур.
End Type - необходим для завершения опеределения пользовательского типа
(оператор Type)
End With - необходим для завершения оператора With.

Пример:

Sub Form_Load
Dim Password, Pword
PassWord = "Swordfish"
Pword = InputBox("Type in your password")
If Pword <> PassWord Then
MsgBox "Sorry, incorrect password"
End
End If
End Sub

[Public | Private] Enum name
membername [= constantexpression]
membername [= constantexpression]
. . .
End Enum

Объявляет перечисляемый тип.

Пример:

Public
          Enum
          InterfaceColors
icMistyRose = &HE1E4FF&
icSlateGray = &H908070&
icDodgerBlue = &HFF901E&
icDeepSkyBlue = &HFFBF00&
icSpringGreen = &H7FFF00&
icForestGreen = &H228B22&
icGoldenrod = &H20A5DA&
icFirebrick = &H2222B2&
End Enum

Erase arraylist - сбрасывает все значения массива фикс. размера и освобождает неиспользуемую память динамического массива.

Пример:

Dim a(5) As Integer
Dim Dyn()
a(2) = 4
ReDim Dyn(10) ' Резирвируем память для 11-ти элементов
Erase a ' Сбрасываем все значения массива a
Erase Dyn ' Освобождаем память
Form1.Caption = a(2) ' Выведет 0
Form1.Caption = Dyn(2) ' Выдаст ошибку Subscript Out Of Range.

Error errornumber - Симулирует наступление ошибки под номером errornumber. Полное описание всех кодов ошибок вы найдёте здесь.

Пример:

On Error Resume Next ' Устанавливаем обработку ошибки
Error 11 ' Симулируем ошибку "Деление на ноль".

[Public] Event procedurename [(arglist)] - Используется для объявления события в компоненте или модуле класса.

Пример:

Public Event UpdateTime(ByVal dblJump As Double)

Exit Do
Exit For
Exit Function
Exit Property
Exit Sub

Используется для досрочного выхода из циклов, функций, свойств и процедур.

Пример:

Sub ExitStatementDemo()
Dim I, MyNum
Do ' Бесконечный цикл
For I = 1 To 1000 ' Повторяем 1000 раз
MyNum = Int(Rnd * 1000) ' Генерируем случайное число
Select Case MyNum ' Проверяем сгенерированное значение
Case 7: Exit For ' Если 7, выходим из For...Next.
Case 29: Exit Do ' Если 29, выходим из Do...Loop.
Case 54: Exit Sub ' Если 54, выходим из процедуры.
End Select
Next I
Loop
End Sub


Операторы VB (F-G)

Описание операторов, встроенных в Visual Basic 5, начинающихся с букв F-G

Список операторов, описанных в этом разделе:

  • FileCopy
  • For Each...Next
  • For...Next
  • Function
  • Get
  • GoSub
  • GoTo

---F---

FileCopy source, destination - копирует файл source в файл destination.

Пример:

FileCopy "C:\Windows\Win.ini", "C:\Backups\Win.bak"

For Each...Next - см. сюда.

For...Next - см. сюда.

[Public | Private | Friend] [Static] Function
          name [(arglist)] [As type]
[statements]
[name = expression]
[Exit Function]
[statements]
[name = expression]
End Function

Этот оператор объявляет функцию с именем name и параметрами arglist.

Пример:

Function CalculateSquareRoot(NumberArg As Double) As Double
If NumberArg < 0 Then ' проверяем аргумент
Exit Function ' Выходим из функции (возвращаясь на то место,
' откуда она была вызвана)
Else
CalculateSquareRoot = Sqr(NumberArg)
' Возвращает квадратный корень аргумента
End If
End Function

---G---

Get [#]filenumber, [recnumber], varname - Читает данные из открытого файла с номером filenumber в переменную varname. recnumber - задаёт позицию начала чтения.

Пример:

' Тип, определяемый пользователем (должен находится в модуле).
Type Record
ID As Integer
Name As String * 20
End Type

Dim MyRecord As Record, Position ' Объявляем переменные
' Открываем файл с произвольным доступом (Random)
Open "TESTFILE" For Random As #1 Len = Len(MyRecord)
Position = 3 ' Устанавливаем позицию начала чтения
Get #1, Position, MyRecord ' Читаем одну запись
Close #1 ' Закрываем файл

GoSub line
...
line
...
Return

Это устаревший оператор перехода в псевдо-подпрограмму с возвращением по Return.
Я категорически НЕ рекомендую его использовать! Это избавит вас от ошибок и плохой читабельности кода. Вполне можно обойтись стандартной процедурой.

GoTo line - оператор для перехода на определённую метку. Пользуйтесь им только в крайних случаях.

Пример:

Dim a, b As Integer
b = 5
a = 1
If a = 1 Then GoTo METKA
b = 10 ' Этот участок никогда не выполнится
METKA:
Debug.Print b ' Выведет цифру 5


Операторы VB (I-L)

Описание операторов, встроенных в Visual Basic 5, начинающихся с букв I-L

Список операторов, описанных в этом разделе:

  • If
  • Implements
  • Input
  • Kill
  • Let
  • Like!!!
  • Line Input
  • Load
  • Lock
  • LSet

---I---

If condition Then [statements] [Else elsestatements] - см. сюда.

Implements [InterfaceName | Class] - Определяет интерфейс или класс, который будет включён в модуль класса. В качестве параметра задаётся либо имя интерфейса, либо имя класса, методы которого будут включены в класс, в котором определён оператор. В общем это вам не плюшки трескать :) А вообще, честно говоря, я и сам толком не понял зачем он нужен. Если Вы можете объяснить, то скиньте описание мне на мыло и я помещу ваше описание сюда.

Input #filenumber, varlist - Последовательно читает данные из файла и записывает их в переменную(ые) varlist.

Пример:

Dim MyString, MyNumber
Open "TESTFILE" For Input As #1 ' Открываем файл для чтения
Do While Not EOF(1) ' Зацикливаемся, пока не конец файла
Input #1, MyString, MyNumber ' Читаем данные в две переменные
Debug.Print MyString, MyNumber ' Печатаем полученные данные в Dubug
Loop
Close #1 ' Закрываем файл

---K---

Kill pathname - Убивает файл! Да-да, именно так! Наверное Билли перед придумываем названия посмотрел какой-нибудь боевичок :) Ну, а если серьёзно, то этот оператор просто удаляет файл с диска. В качестве pathname моно использовать маску.

Пример:

' Удаляем файл
Kill "TestFile"

' Удаляем все файлы с расширением txt, находящиеся в текущей директории
Kill "*.TXT"

---L---

[Let] varname = expression - Это оператор присваивания, который перекачал со старинного бейсика (который я помню ещё со времён спектрума). В общем он необязательный. И использовать его не рекомендую. Но пример всё-таки приведу:

Пример:

Dim MyStr As String

Let MyStr = "Hello World" ' Присваиваем с использованием оператора Let
MyStr = "Hello World" ' То же самое, но без оного.

String Like Pattern- оператор для проверки строки String на маску Pattern. Это очень мощный оператор, почти аналог регулярных выражений в Perl.

Пример:

Dim
        MyCheck
MyCheck = "aBBBa" Like "a*a"
        ' Возвратит True.
MyCheck = "F" Like "[A-Z]"
        ' Возвратит True.
MyCheck = "F" Like "[!A-Z]"
        ' Возвратит False.
MyCheck = "a2a" Like "a#a"
        ' Возвратит True.
MyCheck = "aM5b" Like "a[L-P]#[!c-e]"
        ' Возвратит True.
MyCheck = "BAT123khg" Like "B?T*"
        ' Возвратит True.
MyCheck = "CAT123khg" Like "B?T*"
        ' Возвратит False.

myString = "312T-87GD-8922"

If myString Like "###[A-Z]-##[A-Z][A-Z]-####" Then ...

Спец-символы в маске:

? Любой одиночный символ
* Ноль или более символов
# Любая одиночная цифра (0–9).
[charlist] Любой одиночный символ в классе символов (списке)
[!charlist] Любой одиночный символ не принадлежащий классу символов

Line Input #filenumber, varname - Последовательно читает одну строку из открытого файла в переменную String.

Пример:

Dim TextLine
Open "TESTFILE" For Input As #1 ' Открываем файл
Do While Not EOF(1) ' Зацикливаемся, пока не конец файла
Line Input #1, TextLine ' Читаем в переменную
Debug.Print TextLine ' Печатаем в окно Debug
Loop
Close #1 ' Закрываем файл

Load object - загружает форму или компонент в память. Пример, хоть и большой, но очень простой и понятный.

Пример:

Private Sub Form_Click ()
Dim Answer, Msg As String ' Объявляем переменные
Unload Form1 ' Выгружаем форму
Msg = _
"Form1 только что была выгружена. Нажмите Да, чтобы загрузить её и "
Msg = Msg & "показать. Нажмите Нет чтобы загрузить её и "
Msg = Msg & "оставить невидимой."
Answer = MsgBox(Msg, vbYesNo) ' Выводим окно сообщения
If Answer = vbYes Then ' Проверяем выбор юзера
Show ' если Да, то показываем форму
Else
Load Form1 ' Если Нет, то только загружаем
Msg = "Теперь форма загружена. Нажмите ОК, чтобы показать её."
MsgBox Msg ' Выводим сообщение
Show ' Показываем форму
End If
End Sub

Lock [#]filenumber[, recordrange]
. . .
Unlock [#]filenumber[, recordrange]

Эти операторы управляют доступом к файлу для других процессов, чтобы те не могли что-либо сделать с компонентом этого файла. В приведённом ниже примере после оператора Lock доступ к записи закрывается, и другие процессы (программы) не смогут изменить эту запись. Запись отпирается оператором Unlock.

Пример:

Type Record ' Тип, определённый пользователем (находится в модуле)
ID As Integer
Name As String * 20
End Type

Dim MyRecord As Record, RecordNumber ' Объявляем переменные

' Открываем файл-пример для произвольного доступа
Open "TESTFILE" For Random Shared As #1 Len = Len(MyRecord)

RecordNumber = 4 ' Устанавливаем позицию записи
Lock #1, RecordNumber ' Запираем эту запись
Get #1, RecordNumber, MyRecord ' Читаем запись
MyRecord.ID = 234 ' Модифицируем её
MyRecord.Name = "John Smith"
Put #1, RecordNumber, MyRecord ' Записываем изменённую запись
Unlock #1, RecordNumber ' Отпираем запись

Close #1 ' Закрываем файл

LSet stringvar = string - Выравнивает строку по левой стороне при присваивании ей значения, меньшего по размеру, чем исходная строка. Вместо строк могут использоваться определённые пользователем типы.

Пример:

Dim MyString
MyString = "0123456789" ' Инициализируем строку
Lset MyString = "<-Left" ' MyString содержит "<-Left      "


Операторы VB (M-O)

Описание операторов, встроенных в Visual Basic 5, начинающихся с букв M-O

Список операторов, описанных в этом разделе:

  • Mid
  • MkDir
  • Name
  • On Error
  • Open
  • Option Base
  • Option Compare
  • Option Explicit
  • Option Private

---M---

Mid(stringvar, start[, length]) = string - заменяет символы в строке stringvar начиная с позиции start символами, содержащимися в строке string.

Пример:

Dim
          MyString
MyString = "The dog jumps" ' Инициализируем
          строку
Mid(MyString, 5, 3)
          = "fox" ' MyString = "The fox jumps".
Mid(MyString, 5)
          = "cow" ' MyString = "The cow jumps".
Mid(MyString, 5)
          = "cow jumped over" ' MyString = "The
          cow jumpe".
Mid(MyString, 5, 3)
          = "duck" ' MyString = "The duc
          jumpe".

MkDir path - создаёт каталог path.

Пример:

MkDir "MYDIR" ' Создаёт новую папку в текущем каталоге.
MkDir "C:\MYDIR" ' Создаёт новую папку в корневом каталоге диска С.

---N---

Name oldpathname As newpathname - переименовывает файл или каталог с именем oldpathname в файл или каталог с именем newpathname.

Пример:

Dim OldName, NewName
OldName = "OLDFILE": NewName = "NEWFILE" ' Устанавливаем имена
Name OldName As NewName ' Переименовываем

OldName = "C:\MYDIR\OLDFILE": NewName = "C:\YOURDIR\NEWFILE"
Name OldName As NewName ' Перемещаем и переименовываем файл

---O---

On Error GoTo line
On Error Resume Next
On Error GoTo 0

Устанавливает обработчик ошибок на процедуру. Первый оператор указывает метку, на которую будет передано управление при возникновении ошибки. С помощью второго оператора можно сделать так, чтобы при возникновении ошибки программа продолжала работать. И, наконец, третий позволяет отключить все ранее установленные обработчики ошибок.

Пример:

Dim strVar As String
' Устанавливаем обработчик ошибки
On Error GoTo OSHIBKA
'Открываем несуществующий файл.Возникает ошибка №53 "Файл не найден" и
' программа передаёт управление на метку OSHIBKA
Open "C:\Windows\MyIni.ini" For Input As #3
Input #3, strVar
Close #3
Exit Sub ' Нужно выйти из процедуры, иначе появится ненужный MsgBox

OSHIBKA:
If Err.Number = 53 Then ' Объект Err - содержит свойства ошибки
MsgBox "Файл не найден!", vbCritical, "error"
Else
MsgBox "Какая-то другая ошибка!", vbCritical, "error"
End If

Open pathname For mode [Access access] [lock] As [#]filenumber [Len=reclength] - открывает файл для чтения, записи или для произвольного доступа.

Пример:

' Открываем файл для последовательного чтения
Open "TESTFILE" For Input As #1
' Закрываем файл перед тем, как открыть его снова другим методом
Close #1

' Открываем для двоичного доступа и только для записи
Open "TESTFILE" For Binary Access Write As #1
' Закрываем файл перед тем, как открыть его снова другим методом
Close #1

' Этот пример открывает файл для произвольного доступа.
' Файл содержит записи определённого пользователем типа.

Type Record
ID As Integer
Name As String * 20
End Type

Dim MyRecord As Record ' Объявляем переменную типа запись
Open "TESTFILE" For Random As #1 Len = Len(MyRecord)
' Закрываем файл перед тем, как открыть его снова другим методом
Close #1

' Открываем файл для последовательной записи.
' Причём другие процессы также могут записывать или читать этот файл.

Open "TESTFILE" For Output Shared As #1
' Закрываем файл перед тем, как открыть его снова другим методом
Close #1

'Этот оператор открывает файл для двоичного доступа только для чтения,
' Причём другие процессы не могут обращаться к этому файлу!

Open "TESTFILE" For Binary Access Read Lock Read As #1

Option Base {0 | 1} - задаёт нижний предел для массивов. Оператор действует на уровне модуля. По умолчанию все массивы начинают свои индексы с нуля.

Пример:

Option Base 1 ' Устанавливаем границу для массивов равной единице

Dim Lower
Dim MyArray(20), TwoDArray(3, 4) ' Объявляем массивы
Dim ZeroArray(0 To 5) ' Этот массив всё равно начнётся с нуля
' Используем ф-цию LBound для выявления нижней границы массива
Lower = LBound(MyArray) ' Возвратит 1.
Lower = LBound(TwoDArray, 2) ' Возвратит 1.
Lower = LBound(ZeroArray) ' Возвратит 0.

Option Compare {Binary | Text | Database} - То же, что и выше, только задаёт тип сравнения, который будет использоваться по умолчанию. По умолчанию используется бинарный тип сравнения.

Пример:

' Устанавливаем бинарный тип сравнения.
Option Compare Binary ' Теперь, строка "AAA" меньше, чем "aaa".
' Устанавливаем текстовый тип сравнения.
Option Compare Text ' Теперь, строка "AAA" равна строке "aaa".

Option Explicit - Если задать этот оператор, то нельзя будет использовать необъявленные ранее переменные, например, как в паскале. Подробнее тут.

Пример:

Option Explicit
Dim MyVar ' Объявляем переменную
MyInt = 10
' MyInt - необъявленная переменная, поэтому произойдёт ошибка
MyVar = 10 ' Здесь всё ОК

Option Private Module - делает модуль приватным. Т.е. его методы и функции не могут быть использованы в других подключённых проектах.

Пример:

Option Private Module ' Теперь модуль Module - приватный


Операторы VB (P)

Описание операторов, встроенных в Visual Basic 5, начинающихся с буквы P

Список операторов, описанных в этом разделе:

  • Print
  • Private
  • Property Get
  • Property Let
  • Property Set
  • Public
  • Put

---P---

Print #filenumber, [outputlist] - записывает переменную(ые) outputlist в файл последовательного доступа.

Пример:

Open "TESTFILE" For Output As #1 ' Открыть файл для записи
Print #1, "This is a test"
' Записать в файл строку текста
Print #1,
' Записать в файл пустую строку
Print #1, "Zone 1"; Tab ; "Zone 2"
' Записать информацию в две колонки (зоны)
Print #1, "Hello" ; " " ; "World"
' Разделить строки пробелом
Print #1, Spc(5) ; "5 leading spaces "
' Записать 5 лидирующих пробелов
Print #1, Tab(10) ; "Hello"
' Записать слово в десятый столбец

' Присвоим Boolean, Date, Null и Error значения.
Dim MyBool, MyDate, MyNull, MyError
MyBool = False
MyDate = #February 12, 1969#
MyNull = Null
MyError = CVErr(32767)
' True, False, Null и Error будут преобразованы, основываясь
' на локальных настройках вашей системы.
' Дата запишется, используя стандартный короткий формат
Print #1, MyBool ; " это Boolean значение"
Print #1, MyDate ; " это Дата"
Print #1, MyNull ; " это значение Null"
Print #1, MyError ; " это значение переменной Error"
Close #1 ' Закрываем файл

Private [WithEvents] varname[([subscripts])] [As [New] type] [,[WithEvents] varname[([subscripts])] [As [New] type]] . . .

Объявляет приватные переменные и выделяет под них место в памяти. Пояснение: приватные отличаются от обычных, объявлённых операторм Dim тем, что не может объявлять переменные внутри процедуры или функции. При объявлении в разделе глобальных объявлений они равнозначны.

Пример:

Private Number As Integer ' Объявляем приватную переменную Number
Private NameArray(1 To 5) As String ' Приватный массив
' Несколько объявлений, 2 типа Variant и 1 Integer. Все приватные.
Private MyVar, YourVar, ThisVar As Integer

[Public | Private | Friend] [Static] Property Get
          name [(arglist)] [As type]
[statements]
[name = expression]
[Exit Property]
[statements]
[name = expression]
End Property

Объявляет процедуру получения значения свойства. Эта процедура срабатывает, когда пользователь обращается к свойству.

Пример:

Dim CurrentColor As Integer
Const BLACK = 0, RED = 1, GREEN = 2, BLUE = 3

' Возвращает текущий цвет карандаша (Pen) в виде строки
Property Get PenColor() As String
Select Case CurrentColor
Case RED
PenColor = "Красный"
Case GREEN
PenColor = "Зелёный"
Case BLUE
PenColor = "Синий"
End Select
End Property

' Этот код обращается к свойству и вызывает процедуру Property Get
ColorName = PenColor

[Public | Private | Friend] [Static] Property Let
          name ([arglist,] value)
[statements]
[Exit Property]
[statements]
End Property

Объявляет процедуру присваивания значения свойству. Эта процедура срабатывает, когда пользователь присваивает значение свойству.

Пример:

Dim CurrentColor As Integer
Const BLACK = 0, RED = 1, GREEN = 2, BLUE = 3

' Устанавливает цвет карандаша(Pen) по цвету, указанному в виде строки
' Переменной уровня модуля CurrentColor присваивается
' текущий цвет карандаша
Property Let PenColor(ColorName As String)
Select Case ColorName ' Проверяем строку, определяющую цвет
Case "Красный"
CurrentColor = RED ' Красный цвет
Case "Зелёный"
CurrentColor = GREEN ' Зелёный
Case "Синий"
CurrentColor = BLUE ' Синий
Case Else
CurrentColor = BLACK ' Присваиваем значение по умолчанию
End Select
End Property

' Этот код вызывает процедуру Property Let
PenColor = "Красный"

[Public | Private | Friend] [Static] Property Set
          name ([arglist,] reference)
[statements]
[Exit Property]
[statements]
End Property

Объявляет процедуру присваивания свойству ссылки на объект. Эта процедура срабатывает, когда пользователь присваивает свойству ссылку на объект. Например, если тип свойства - Picture.

Пример:

' Свойство DownPicture может иметь различные картинки
' CurrentPic - хранит рисунок
Property Set DownPicture(P As Picture)
Set CurrentPic = P ' Присваиваем новый рисунок
End Property

Public [WithEvents] varname[([subscripts])] [As [New] type] [,[WithEvents] varname[([subscripts])] [As [New] type]] . . .

Объявляет глобальную переменную. Объявлённая таким способом переменная становится доступной из всех модулей и форм проекта. Если переменная объявлена в разделе глобальных объявлений, то доступ к ней осуществляется просто по её имени. Если же она объявлена в коде формы, то доступ к ней из других форм и модулей осуществляется так: ИмяФормы.ИмяПеременной.

Пример:

Public Number As Integer ' Глобальная переменная типа Integer
Public NameArray(1 To 5) As String ' Глобальный массив
' Несколько объявлений, 2 типа Variant и 1 Integer. Все глобальные.
Public MyVar, YourVar, ThisVar As Integer

Put [#]filenumber, [recnumber], varname - Записывает данные в файл с номером filenumber из переменной varname. recnumber - задаёт позицию начала записи.

Пример:

Type Record ' Определённый пользователем тип
ID As Integer
Name As String * 20
End Type

Dim MyRecord As Record, RecordNumber ' Объявляем переменные
' Открываем файл для произвольного доступа
Open "TESTFILE" For Random As #1 Len = Len(MyRecord)
For RecordNumber = 1 To 5 ' Циклимся 5 раз
MyRecord.ID = RecordNumber ' Устанавливаем компоненту ID
MyRecord.Name = "My Name" & RecordNumber ' Создаём строку
Put #1, RecordNumber, MyRecord ' Записываем запись в файл
Next RecordNumber
Close #1 ' Закрываем файл


Операторы VB (R)

Описание операторов, встроенных в Visual Basic 5, начинающихся с буквы R

Список операторов, описанных в этом разделе:

  • RaiseEvent
  • Randomize
  • ReDim
  • Rem
  • Reset
  • Resume
  • RmDir
  • RSet

---R---

RaiseEvent eventname [(argumentlist)] - Запускает событие, определённое в компоненте, форме или документе.

Пример:

' В этом примере при нажатии на UserControl будет
' генерироваться нажатие клавиши с кодом 101

Event Click()
Event KeyPress(KeyAscii As Integer)

Private Sub UserControl_Click()
RaiseEvent KeyPress(101) ' Вместо щелчка будет происходить KeyPress
End Sub

Private Sub UserControl_KeyPress(KeyAscii As Integer)
RaiseEvent KeyPress(KeyAscii) ' Обычный KeyPress
End Sub

' Теперь поместите этот код в форму, на которой расположен UserControl

Private Sub UserControl1_KeyPress(KeyAscii As Integer)
MsgBox "Hello World " & KeyAscii
End Sub

' Запустите проект и щёлкните по UserControl'у.

Randomize [number] - Инициализирует генератор случайных чисел. Если этот оператор не поместить перед функцией Rnd, то при каждом запуске приложения будут генерироваться одни и те же случайные числа.

Пример:

Dim MyValue
Randomize ' Инициализирует генератор случайных чисел

MyValue = Int((6 * Rnd) + 1) ' Генерируем случайное число от 1 до 6

ReDim [Preserve] varname(subscripts) [As type] [, varname(subscripts) [As type]] . . .

Изменяет размер динамического массива. Замечание: Для этого оператора Option Base установлен в единицу!

Пример:

Dim MyArray() As Integer ' Объявляем динамический массив
Redim MyArray(5) ' Выделяем место для ПЯТИ элементов
For I = 1 To 5 ' Циклимся 5 раз
MyArray(I) = I ' Присваиваем значения компонентам массива
Next I

' Следующий оператор изменяет размер массива и очищает его

Redim MyArray(10) ' Теперь размер массива = 10
For I = 1 To 10 ' Циклимся 10 раз
MyArray(I) = I ' Присваиваем значения компонентам массива
Next I

' А этот оператор изменяет размер, но не очищает его

Redim Preserve MyArray(15) ' Теперь размер = 15

Rem comment - старый оператор для создания комментариев в тексте программы. Лучше использовать новый аналог - ' (апостроф).

Пример:

Dim MyStr1, MyStr2
MyStr1 = "Hello": Rem Здесь ваш комментарий
MyStr2 = "Goodbye" ' Это тоже комментарий, только без двоеточия

Reset - закрывает все файлы, открытые оператором Open.

Пример:

Dim FileNumber
For FileNumber = 1 To 5 ' Циклимся 5 раз
'Откроем файл для записи с номером FileNumber и к имени прибавим номер
Open "TEST" & FileNumber For Output As #FileNumber
Write #FileNumber, "Hello World" ' Записываем данные в файл
Next FileNumber
' Закрываем все открытые файлы и записываем их содержимое на диск
Reset

Resume [0]
Resume Next
Resume line

Возобновляет выполнение программы после обработки ошибки.

Пример:

Sub ResumeStatementDemo()
On Error GoTo ErrorHandler ' Включаем обработчик ошибок
Open "TESTFILE" For Output As #1 ' Открываем файл
Kill "TESTFILE" ' Пытаемся удалить открытый файл
Exit Sub ' Выходим из процедуры, чтобы обойти обработчик ошибки
ErrorHandler: ' Начало обработчика
Select Case Err.Number ' Проверяем номер ошибки
Case 55 ' Ошибка "Файл уже открыт"
Close #1 ' Закрываем открытый файл
Case Else
' Здесь обрабатываем другие ситуации...

End Select
Resume ' Продолжаем выполнение программы с той же строки,
' в которой произошла ошибка
End Sub

RmDir path - удаляет директорию с диска.

Пример:

RmDir "C:\Temp" ' Удаляет директорию Temp с корневого диска

RSet stringvar = string - Выравнивает строку по правой стороне при присваивании ей значения, меньшего по размеру, чем исходная строка. Вместо строк могут использоваться определённые пользователем типы.

Пример:

Dim MyString
MyString = "0123456789" ' Инициализируем строку
Rset MyString = "Right->" ' MyString содержит "     Right->"


Операторы VB (S)

Описание операторов, встроенных в Visual Basic 5, начинающихся с буквы S

Список операторов, описанных в этом разделе:

  • SavePicture
  • SaveSetting
  • Seek
  • Select Case
  • SendKeys
  • Set
  • SetAttr
  • Static
  • Stop
  • Sub

---S---

SavePicture picture, stringexpression - сохраняет изображение, находящееся в данный момент в свойствах Picture или Image объекта X в файл.

Пример:

' Поместите на форму PictureBox и загрузите туда любую картинку

Private Sub Form_Click()
AutoRedraw = True ' Включаем перерисовку окна
Picture1.AutoRedraw = True
Form1.ScaleMode = vbPixels ' Ставим вид масштаба в пиксели
Picture1.ScaleMode = vbPixels
Form1.PaintPicture Picture1, 0, 0, 100, 100, 0, 0, 100, 100, vbSrcCopy
Form1.Refresh
MsgBox "Нажмите OK для сохранения"
SavePicture Image, "C:\TEST.BMP" ' Сохраняем картинку
End Sub

SaveSetting appname, section, key, setting - Записывает настройку в реестр. Напомню, что функция DeleteSetting удаляет настройку, а функция GetSetting загружает. Я почему-то не нашёл в документации путь, куда сохраняются настройки. Пришлось определять самому. Оказалось, что настройки записываются по адресу:
HKEY_CURRENT_USER\SOFTWARE\VB and VBA Program Settings
В этом ключе создаётся ещё один ключ с названием appname.

Пример:

' Сохраняем положение левой координаты формы в реестр
SaveSetting "MyApp", "Startup", "Left", Form1.Left

Seek [#]filenumber, position - Устанавливает позицию для чтения/записи в файле, открытым оператором Open.

Пример:

Type Record ' Определённый пользователем тип
ID As Integer
Name As String * 20
End Type

' Для файлов, открытых для произвольного доступа,
' Seek устанавливает следующую запись

Dim MyRecord As Record, MaxSize, RecordNumber ' Объявляем переменные
' Открываем файл для произвольного доступа
Open "TESTFILE" For Random As #1 Len = Len(MyRecord)
MaxSize = LOF(1) \ Len(MyRecord) ' Получаем количество записей в файле
' Цикл читает записи с конца до начала
For RecordNumber = MaxSize To 1 Step - 1
Seek #1, RecordNumber ' Устанавливаем позицию записи
Get #1, , MyRecord ' Читаем запись
Next RecordNumber
Close #1 ' Закрываем файл

' Для файлов, окрытых не для произвольного доступа,
' Seek устанавливает позицию с точностью до байта.

Dim MaxSize, NextChar, MyChar
Open "TESTFILE" For Input As #1 ' Открываем файл
MaxSize = LOF(1) ' Получаем размер файла в байтах
' Цикл читает по букве с конца файла до начала
For NextChar = MaxSize To 1 Step -1
Seek #1, NextChar ' Устанавливаем позицию
MyChar = Input(1, #1) ' Читаем символ
Next NextChar
Close #1 ' Закрываем файл

Select Case - см. сюда.

SendKeys string[, wait] - посылает одно или более нажатий на клавишу в активное окно. Всё происходит точно так же, как будто всё было введено с клавиатуры.

Пример:

Dim ReturnValue, I
ReturnValue = Shell("CALC.EXE", 1) ' Запускаем калькулятор
AppActivate ReturnValue ' Активизируем калькулятор
For I = 1 To 100 ' Циклимся 100 раз
SendKeys I & "{+}", True ' Посылаем нажатие на клавишу в калькулятор
Next I ' Добавляем к значению в калькуляторе переменную I
SendKeys "=", True ' Нажимаем на знак равенства
SendKeys "%{F4}", True ' Посылаем Alt+F4 для закрытия калькулятора

Set objectvar = {[New] objectexpression | Nothing} - присваивает переменной ссылку на объект.

Пример:

Dim YourObject, MyObject, MyStr
Set MyObject = YourObject ' Присваиваем ссылку
' MyObject иYourObject ссылаются на один и тот же объект
YourObject.Text = "Hello World" ' Инициализируем свойство
MyStr = MyObject.Text ' Возвратит "Hello World".

' Удаляем ссылку на объект
Set MyObject = Nothing ' Освобождаем объект

SetAttr pathname, attributes - устанавливает атрибуты файла pathname.

Пример:

SetAttr "TESTFILE", vbHidden
' Теперь файл скрытый
SetAttr "TESTFILE", vbHidden + vbReadOnly
' Теперь он и скрытый и только для чтения

Static varname[([subscripts])] [As [New] type] [, varname[([subscripts])] [As [New] type]]...

Объявляет переменную. Переменные Static объявляются внутри процедур и функций и вне их недоступны, но в отличие от обычных локальных переменных они не инициализируются при входе в процедуру или функцию, где они объявлены.

Пример:

' Определение функции
Function KeepTotal(Number)
' Только переменная Accumulate сохраняет своё значение между вызовами
Static Accumulate
Accumulate = Accumulate + Number
KeepTotal = Accumulate
End Function

' Определение статической функции
Static Function MyFunction(Arg1, Arg2, Arg3)
' Все локальные переменные сохраняют свои значения между вызовами
Accumulate = Arg1 + Arg2 + Arg3
Half = Accumulate / 2
MyFunction = Half
End Function

Stop - С помощью этого оператора можно поставить брикпоинт в программе. Если же программу скомпилировать с этим оператором и запустить, то при наступлении это оператора программа выдаст ошибку. В отличие от оператора End, оператор Stop не закрывает открытые файлы и не очищает переменные.

Пример:

Dim I
For I = 1 To 10 ' Запускаем цикл
Debug.Print I ' Печатаем I в Debug
Stop ' Останавливаемся на каждой итерации
Next I

[Private | Public | Friend] [Static] Sub name
          [(arglist)]
[statements]
[Exit Sub]
[statements]
End Sub

Этот оператор объявляет процедуру с именем name и параметрами arglist.

Пример:

'
          Объявляем процедуру
' Процедура имеет 2 аргумента
Sub SubComputeArea(Length, TheWidth)
Dim Area As Double
          ' Объявляем локальную переменную
If Length = 0 Or
          TheWidth = 0 Then
' Если любой аргумент равен нулю
Exit Sub ' Сразу
          выходим из процедуры
End If
Area = Length * TheWidth ' Вычисляем площадь прямоугольника
Debug.Print
          Area ' Печатаем её в окно Debug
End Sub


Операторы VB (T-W)

Описание операторов, встроенных в Visual Basic 5, начинающихся с букв T-W

Список операторов, описанных в этом разделе:

  • Time
  • Type
  • Unload
  • Unlock
  • While...Wend
  • Width
  • With
  • Write

---T---

Time = time - Изменяет системное время на time.

Пример:

Dim MyTime
MyTime = #4:35:17 PM# ' Присваиваем время переменной
Time = MyTime ' Изменяем системное время

[Private | Public] Type varname
elementname [([subscripts])] As type
[elementname [([subscripts])] As type]
. . .
End Type

Объявляет новый тип (тип, определённый пользователем), содержащий один или несколько элементов.

Пример:

Type EmployeeRecord ' Создаём новый тип
ID As Integer ' Определяем типы значений, входящие в новый тип
Name As String * 20
Address As String * 30
Phone As Long
HireDate As Date
End Type

Sub
          CreateRecord()
Dim MyRecord As
          EmployeeRecord ' Объявляем переменную
' Присвоение значения переменной типа EmployeeRecord
' должно произойти в процедуре
MyRecord.ID = 12003 ' Присваиваем значение элементу
          переменной
End Sub

---U---

Unload object - Выгружает объект (форму или компонент). Эта функция является обратной функции Load.

Пример:

Private Sub Form_Click ()
Dim Answer, Msg As String ' Объявляем переменные
Unload Form1 ' Выгружаем форму
Msg = _
"Form1 только что была выгружена. Нажмите Да, чтобы загрузить её и "
Msg = Msg & "показать. Нажмите Нет чтобы загрузить её и "
Msg = Msg & "оставить невидимой."
Answer = MsgBox(Msg, vbYesNo) ' Выводим окно сообщения
If Answer = vbYes Then ' Проверяем выбор юзера
Show ' если Да, то показываем форму
Else
Load Form1 ' Если Нет, то только загружаем
Msg = "Теперь форма загружена. Нажмите ОК, чтобы показать её."
MsgBox Msg ' Выводим сообщение
Show ' Показываем форму
End If
End Sub

Lock [#]filenumber[, recordrange]
. . .
Unlock [#]filenumber[, recordrange]

Эти операторы управляют доступом к файлу для других процессов, чтобы те не могли что-либо сделать с компонентом этого файла. В приведённом ниже примере после оператора Lock доступ к записи закрывается, и другие процессы (программы) не смогут изменить эту запись. Запись отпирается оператором Unlock.

Пример:

Type Record ' Тип, определённый пользователем (находится в модуле)
ID As Integer
Name As String * 20
End Type

Dim MyRecord As Record, RecordNumber ' Объявляем переменные

' Открываем файл-пример для произвольного доступа
Open "TESTFILE" For Random Shared As #1 Len = Len(MyRecord)

RecordNumber = 4 ' Устанавливаем позицию записи
Lock #1, RecordNumber ' Запираем эту запись
Get #1, RecordNumber, MyRecord ' Читаем запись
MyRecord.ID = 234 ' Модифицируем её
MyRecord.Name = "John Smith"
Put #1, RecordNumber, MyRecord ' Записываем изменённую запись
Unlock #1, RecordNumber ' Отпираем запись

Close #1 ' Закрываем файл

---W---

While...Wend - Оператор цикла. Отличие от оператора Do While...Loop заключается в том, что здесь не используется слово Do, и вместо слова Loop используется Wend. В общем выбирайте какой хотите.

Пример:

Dim Counter
Counter = 0 ' Инициализируем переменные
While Counter < 20 ' Проверяем значение счётчика
Counter = Counter + 1 ' Увеличиваем счётчик
Wend ' Заканчиваем цикл, если Counter > 19
Debug.Print Counter ' Печатаем 20 в окно Debug

' Этот же пример, только с циклом Do While:

Dim Counter
Counter = 0 ' Инициализируем переменные
Do While Counter < 20 ' Проверяем значение счётчика
Counter = Counter + 1 ' Увеличиваем счётчик
Loop ' Заканчиваем цикл, если Counter > 19
Debug.Print Counter ' Печатаем 20 в окно Debug

Width #filenumber, width - Устанавливает длину строки при выводе в файл, открытый оператором Open.

Пример:

Dim I
Open "TESTFILE" For Output As #1 ' Открываем файл для записи
Width #1, 5 ' Устанавливаем длину вывода 5
For I = 0 To 9 ' Циклимся 10 раз
Print #1, Chr(48 + I); ' Выводим по 5 символов в строке
Next I
Close #1 ' Закрываем файл

With object
[statements]
End With

С помощью этого оператора можно произвести серию обращений к объекту или переменной типа запись. Таким образом код становится короче и понятнее.

Пример:

With
          MyObject
.Height = 100
' Аналогично выражению MyObject.Height = 100.
.Caption = "Hello World"
' Аналогично выражению MyObject.Caption = "Hello
          World".
With .Font
.Color = Red ' Аналогично выражению MyObject.Font.Color
          = Red.
.Bold = True ' Аналогично
          выражению MyObject.Font.Bold = True.
End With
End With

Write #filenumber, [outputlist] - последовательно записывает данные в файл.

Пример:

Open "TESTFILE" For Output As #1 ' Открываем файл для записи
Write #1, "Hello World", 234 ' Записываем строку, разделённую запятой
Write #1, ' Записываем пустую линию

Dim MyBool, MyDate, MyNull, MyError
' Присваиваем Boolean, Date, Null и Error значения
MyBool = False
MyDate = #February 12, 1969#
MyNull = Null
MyError = CVErr(32767)
' Boolean запишется как #TRUE# или #FALSE#. Дата запишется
' как #1969-01-12#. Null запишется как #NULL#.
' Error капишется как #ERROR код_ошибки#.
Write #1, MyBool ; " это Boolean значение
Write #1, MyDate ; " это Дата"
Write #1, MyNull ; " это Null"
Write #1, MyError ; " а это Error"
Close #1 ' Закрываем файл


ActiveX в Visual Basic

Современный программист, работающий в среде Visual Basic, неизбежно столкнется с технологией ActiveX, которая и является темой данной главы. Управляющие элементы для работы в Internet или внешние утилиты (Add-Ins) для расширения возможностей IDE — все это ActiveX. Более того, значение технологии ActiveX выходит далеко за рамки Visual Basic — это стратегическое направление, которое избрала корпорация Microsoft в вопросах развития современных технологий программирования. Почти все программные продукты Microsoft располагают в той или иной мере способностью предоставлять свои функциональные возможности другим приложениям или пользоваться функциональными возможностями других приложений (так называемая объектная модель). В этом плане выдвижение на передний план технологии ActiveX является, с одной стороны, развитием объектной модели, а с другой — ответом корпорации Microsoft на появление языка Java, который продвигает компания Sun Microsystems и который претендует на роль макроязыка среды Internet.

Чтобы понять истоки технологии ActiveX, необходимо проанализировать путь, по которому развивалась сама идея объектной модели.

СОМ

Задолго до появления терминов OLE (и, уж тем более, ActiveX) разработчикам из Microsoft пришла в голову мысль о программном объекте, независимом от языка, на котором пишется программа. Так родилась технология СОМ (Component Object Model — компонент, основанный на объектной модели). Спецификация СОМ определяла правила, которых должен был придерживаться программный объект, находящийся в оперативной памяти компьютера. При этом не имело значения, с помощью какого

языка программирования создан данный объект, спецификация СОМ задавала правила поведения для программного объекта вообще (это включало в себя формат размещения объекта в памяти, а также протокол взаимодействия объекта с окружающей программной средой).

С появлением спецификации СОМ был заложен фундамент многократно используемых компонентов, которые могли участвовать во многих проектах, не изменяя своего кода.

OLE

Вскоре после СОМ на свет появилась технология OLE (Object Linking and Embedding — связывание и внедрение объектов). Первоначальной целью Microsoft была документная ориентация среды Windows. Но по прошествии времени технология OLE стала фактическим стандартом для многократно используемого кода. Практически речь шла о развитии спецификации СОМ — при этом технология OLE позволяла на правах «многократно используемого кода» создавать управляющие элементы, организовывать управление версиями объектов, а также осуществлять связывание и внедрение объектов.

ActiveX

С помощью технологии ActiveX корпорация Microsoft намеревается завоевать Internet. Корни ActiveX лежат в технологии OLE, которую разработчики из Microsoft распространили на Internet-приложения. В результате управляющие элементы, созданные в соответствии с требованиями технологии ActiveX должны выполняться в среде Internet, что способно необычайно расширить функциональные возможности Visual Basic-программ, использующих ActiveX-элементы.

DCOM

DOOM (Distributed СОМ ) представляет собой расширение стандарта СОМ. В отличие от первоисточника (стандарт СОМ определял «правила поведения» программного объекта в памяти) DCOM специфицирует интерфейс между программными объектами, средой взаимодействия которых является Internet. Ниже представлена терминология OLE/ActiveX в языке Visual Basic 5.

Термин OLE | Термин ActiveX | Описание
OLE-объект | OLE-объект | Связываемый или внедряемый объект, содержащийся в OLE-элементе (OLE-контейнере).
Объект OLE-Automation | ActiveX-объект | Доступный для программирования объест, разрешающий доступ к своим свойствам и методам извне.
OLE-сервер (визуальный) | OLE-сервер (визуальный) | Приложение, располагающее связываемым или внедряемым объектом.
OLE-сервер (программируемый) | ActiveX. EXE | Приложение, предоставляющее другим приложениям связываемый или внедряемый объект.
OLE DLL | ActiveX.DLL | DLL-библиотека, содержащая доступный для программирования объект.
Custom Control | ActiveX Control | Управляющий элемент, который может функционировать в составе приложения независимо от языков программирования, на которых написано приложение и сам элемент.
нет соответствия | ActiveX Document.EXE | Приложение, которое Microsoft Internet Explorer может интерпретировать в качестве Web-страницы.
нет соответствия | ActiveX Document.DLL | Компонент, который может быть интерпретирован в качестве Web-страницы.

Дополнительные управляющие элементы

Технология ActiveX играет важную роль в среде Visual Basic еще и потому, что дополнительные управляющие элементы включаются в состав программы в форме ActiveX-элементов. При этом обращаться с ними в процессе визуального программирования можно так же, как и со стандартными элементами.

Обзор:

  • Прежде чем дополнительный управляющий элемент можно будет использовать, его необходимо включить в состав коллекции инструментов для данного проекта. Однако элемент при этом должен быть предварительно зарегистрирован в системе. Регистрация большинства элементов выполняется автоматически при их установке, явным образом это можно сделать с помощью системной утилиты regsvr32.exe.
  • Зарегистрированный элемент можно включить в состав коллекции инструментов посредством диалога Components (одноименная команда меню Project). Вкладка Controls этого диалога содержит список зарегистрированных элементов — достаточно поставить пометку (галочку) напротив имени элемента и щелкнуть на ОК, и значок элемента появится в окне коллекции инструментов, откуда его можно поместить на форму обычным способом.
  • Как и стандартные, дополнительные управляющие элементы обладают свойствами, методами и событиями. Кроме обычного способа доступа к свойствам на этапе визуального программирования многие из дополнительных управляющих элементов дают возможность открыть диалог Property Pages (одноименная команда меню View или [Shift]+[F4]), где обеспечивается более удобный доступ к некоторым свойствам.
  • Как только дополнительный элемент включен в состав проекта, информация о его свойствах, методах, событиях и константах становится доступной в каталоге объектов ([F2] или команда Object Browser меню View).

Дополнительные управляющие элементы Visual Basic

Точный состав набора дополнительных элементов, поставляемых в составе пакета Visual Basic, зависит от варианта (издания) пакета. В частности, MAPI-элементы и элемент Internet Transfer имеются только в профессиональных вариантах Visual Basic.


Компонентная Объектная Модель

Компонентная Объектная Модель (СОМ) — архитектура промышленного стандарта для объектно-ориентированной разработки приложений и основа для формирования компонентов ActiveX. Компонент ActiveX — физический файл (например, .exe, .dll, .ocx), который содержит классы, представляющие определения объектов. Эти объекты можно подключать и использовать в приложении Visual Basic. Компоненты ActiveX позволяют программистам объединять в приложении порции кода многократного использования.

Для решения общих задач, таких, как числовой анализ или формирование элементов пользовательского интерфейса, разработчик может создавать свои собственные компоненты ActiveX или использовать подключаемые компоненты Microsoft или сторонних разработчиков. При создании в приложении пользовательских решений можно объединять компоненты ActiveX с общими компонентами.

Компонентная Объектная Модель

Для формирования эффективных современных приложений-клиентов требуется иметь представление относительно компонентов сервера, используемых клиентом; требуется также понимание базовой технологии СОМ, посредством которой клиент соединяется с этими компонентами. С СОМ связаны два различных аспекта. Во-первых, спецификация СОМ обеспечивает определение (или модель) для объекта. Во-вторых, СОМ обеспечивает возможности для создания объектов и организации связи между клиентом и сервером.

В этом разделе предлагается краткий обзор СОМ — мощного дополнения к комплекту инструментальных средств разработчика. Здесь описываются умолчательные интерфейсы, обеспечиваемые объектами СОМ, показывается, как объекты поддерживают связь с клиентами и как использовать клиенты при создании и использовании экземпляра объекта. Для лучшего понимания СОМ полезно ознакомиться со следующими терминами и определениями:

Компонент — единица исполняемого кода, которая предоставляет некоторые функциональные возможности. Компоненты обеспечиваются серверами, которые представлены файлами .exe, .dll или .ocx. Серверы могут быть построены из одного или больше компонентов; компоненты обеспечивают шаблоны, из которых затем создаются объекты. Компонентная Объектная Модель определяет, как компоненты создаются и как приложения-клиенты соединяются с компонентами. СОМ также обрабатывает запросы из приложений-клиентов на создание объектов.

Объект — комбинация кода и данных, которые могут обрабатываться как единица. Объект имеет период существования, то есть он создается и разрушается.

Автоматика — часть спецификации СОМ, которая определяет стандартную методику создания компонентов и использования объектов.

Объект Автоматики — объект, который предоставлен другим приложением или инструментальным средством программирования через интерфейсы Автоматики. Объекты Автоматики также известны как программируемые объекты. Программируемый объект может управляться программным способом посредством его методов и свойств (интерфейс объекта).

Разработчику приложения-клиента объект предоставляет возможность ввода информации или запроса и обеспечивает вывод, но внутренняя организация объекта разработчику недоступна. Разработчики должны лишь понимать, как использовать предоставляемые объектом функциональные возможности. Эти функциональные возможности предоставляются через один или несколько интерфейсов. Интерфейсы — средства (свойства и методы), посредством которых приложения-клиенты сообщаются с компонентом.

Краткая история СОМ

Целью разработки идеологии СОМ было сделать приложения более настраиваемыми и гибкими, причем главной задачей была поддержка концепции, известной как связывание и внедрение объектов. Идея состояла в том, чтобы получать документ-ориентированное приложение, работая в котором, например, можно было бы редактировать электронную таблицу из текстового процессора. Версия Microsoft технологии связывания и внедрения объектов называется OLE. В первой версии OLE для поддержания связи между клиентом и компонентом использовалось нечто, именуемое DDE (Dynamic Data Exchange —динамический обмен данными). В OLE 1 ни о какой СОМ речи не шло. DDE был сформирован на верхнем уровне архитектуры передачи сообщений Windows. Технология DDE была далека от совершенства. DDE работает медленно и недостаточно гибко. Кроме того, трудно написать код для DDE, который работает правильно. Эти серьезные недостатки свидетельствовали о том, что поиски должны быть продолжены.

Решением было СОМ. СОМ меньше по ресурсам, работает быстрее, значительно более устойчивая и гибкая чем DDE. Во второй версии OLE было модернизировано с использованием СОМ вместо DDE. Однако OLE было первой системой, разработанной на базе СОМ. В OLE не реализовано все то, что может обеспечить СОМ. OLE имеет репутацию системы, также работающей медленно и сложной в программировании. Впрочем, причина этих проблем — в реализации OLE, это не результат использования СОМ.

Все же следует помнить, что в OLE сделана попытка реализовать многие прежде недоступные возможности. Посредством OLE можно помещать изображение из графической программы одного разработчика в текстовый процессор другого разработчика и редактировать его, не покидая текстовый процессор. Протокол OLE определяет многофункциональную связь между клиентом и компонентом. Компонент может многое, а приложение-клиент должно быть к этому готово. Это, однако, делает OLE очень трудным в программировании.

СОМ — не компьютерный язык и не конкурирует с ними. Рассуждения относительно того, что лучше: C++ или СОМ или наоборот, не имеет никакого смысла, так как перед СОМ и C++ стоят разные задачи. СОМ сообщает программисту, как строить компоненты, и программист свободен в выборе языка, на котором он будет писать компоненты. Часто компоненты пишутся на C++. Сегодня это позволяет делать и Visual Basic.

Компонентные приложения

Исполняемая часть приложения часто состоит из единственного монолитного двоичного файла. После того как компилятор генерирует приложение, оно не изменяется, пока не будет скомпилирована следующая версия. Изменения в операционных системах, аппаратных средствах и желаниях заказчика вынуждают разработчика вносить изменения и перекомпилировать приложение. В этих условиях разработчики должны искать способы продлить период существования уже созданных приложений. Решение состоит в том, чтобы разбить монолитное приложение на отдельные части, или компоненты.

По мере совершенствования технологий новые компоненты могут заменять существующие компоненты, формирующие приложение. Приложение — более не статичный объект, оно может развиваться с появлением более эффективных компонентов. Более того, из существующих компонентов может быть быстро построено полностью новое приложение.

Компонент A | Компонент B
Компонент C | Компонент D
Монолитное приложение
Компонентное приложение

Традиционно приложение разделялось на файлы, модули или классы, которые компилировались и компоновались для создания приложения. Формирование приложений из компонентов — процесс несколько иной. Компонент подобен мини-приложению; он поставляется упакованным, как функциональная порция двоичного кода, которая скомпилирована, скомпонована и полностью готова к употреблению. Монолитное приложение уступает место группе компонентов, которые для формирования приложения соединяются друг с другом в период выполнения.

Изменение или расширение приложения — простой вопрос замены одного из этих составляющих компонентов его новой версией или другим компонентом. Разбиение монолитного приложения на компоненты поддерживается механизмами СОМ.

Компонент A | Компонент B
Компонент C | Новый Компонент D

Компонентное приложение
Замена старого компонента - новым.

Облегчение настройки приложения

Пользователи часто хотят иметь возможность настраивать приложение под свои потребности и вкусы. В случае монолитного приложения конечный пользователь должен все время общаться с программистом, давая ему заявки на реализацию того или иного пользовательского решения. Компонентные архитектуры облегчают настройку приложения, так как каждый компонент может быть заменен на другой, который лучше удовлетворяет потребностям пользователя.

Предположим, что имеются компоненты, основанные на графических редакторах Paint и Photo Shop. На иллюстрации внизу Пользователь 1 сконфигурировал приложение, чтобы использовать Paint, в то время как Пользователь 2 предпочитает Photo Shop. Приложение может быть легко настроено добавлением новых компонентов или изменением существующих компонентов.

Компонент A | Компонент B
Компонент C | Компонент D
Редактор Paint

Компонент A | Компонент B
Компонент C | Компонент D
Редактор Photoshop
Пользователь 1
Пользователь 2

Библиотеки компонентов

Одно из больших преимуществ компонентной архитектуры — быстрая разработка приложения. СОМ позволяет выбирать компоненты из библиотеки компонентов и складывать их вместе при формировании приложения, подобно строительным блокам.

Построение приложений из стандартных частей долгое время было неосуществимой мечтой разработчиков программного обеспечения. Однако с появлением элементов управления ActiveX, ранее называвшихся элементами управления OLE, "процесс пошел". Программисты на Visual Basic, С, C++ и Java могут использовать преимущества элементов управления ActiveX для ускорения разработки своих приложений и Web-страниц. В приложениях, конечно, потребуется создавать также некоторые пользовательские компоненты однако большая часть приложения может быть сформирована с использованием стандяр тных компонентов.

Требования к компонентам

Преимущества использования компонентов непосредственно вытекают из их способности динамически подключаться и отключаться из приложения. Для достижения этой возможности компоненты должны отвечать двум требованиям. Во-первых, компоненты должны обеспечить возможность динамической компоновки. Во-вторых, компоненты должны скрывать (или инкапсулировать) подробности их реализации. Определить, какое требование является более важным, — значит решать проблему яйца и курицы. Каждое требование зависит от другого. Можно остановиться на таком определении: динамическая компоновка — определяющее требование для компонента, а скрывание информации — необходимое условие для динамической компоновки. Ниже эти два требования исследуются более подробно.

Динамическая компоновка

Для понимания важности динамической компоновки можно представить себе приложение, сформированное из компонентов, которые не могут связываться в период выполнения. Если нужно изменить один из компонентов в системе, потребуется статически повторно скомпоновать или перекомпилировать программу и затем перераспределить ее. Разработчик не может ожидать, что конечные пользователи его приложения смогут повторно скомпоновать и скомпилировать приложение самостоятельно. Даже если бы они знали, как это делать, у них, наиболее вероятно, неоказалось бы требуемого компилятора. Приложение, созданное из компонентов, которые должны статически перекомпилироваться каждый раз при необходимости внести изменения, эквивалентно монолитному приложению.

Инкапсуляция

Почему динамическая компоновка требует инкапсуляции? При формировании приложения компоненты соединяются друг с другом. Если требуется заменить компонент на новый компонент, необходимо отключить старый компонент от системы и затем подключить новый. Новый компонент должен подключаться тем же самым способом, что и старый компонент, иначе потребуется переписать код, перекомпилировать или повторно скомпоновать эти компоненты. В данном случае не имеет значения, поддерживают ли компоненты и приложение динамическую связь. Если изменяется способ соединения компонента с другими компонентами, нарушается система компонентов и, по крайней мере, придется перекомпилировать, если не переписать приложение.

Для понимания, как все это связано с инкапсуляцией, нужно ввести некоторые определения. Программа или компонент, который использует другой компонент, называется клиентом. Клиент соединен с компонентом через интерфейс. Если компонент изменяется без изменения интерфейса, для клиента ничего не должно измениться. Аналогично, если изменяется клиент без изменения интерфейса, компонент не должен изменяться. Однако, если при изменении или компонента, или клиента изменяется интерфейс, другая сторона интерфейса также должна измениться.

Следовательно, чтобы использовать преимущества динамической компоновки, компоненты и клиенты должны стремиться не изменять их интерфейсы. Они должны быть скрыты. Подробности относительно того, как реализованы клиент и компонент, не должны быть отражены в интерфейсе. Чем больше интерфейс изолирован от подробностей реализации, тем меньше вероятность того, что в результате изменения клиента или компонента изменится интерфейс. Если интерфейс не изменяется, изменение компонента не будет иметь никакого эффекта для остальной части приложения.

Изоляция клиента от реализации компонента накладывает на компонент некоторые важные ограничения:

  1. Компонент должен скрыть компьютерный язык, используемый для его реализации. Любое приложение— клиент должно иметь возможность использовать любой компонент независимо от компьютерного языка, на котором написано приложение или компонент. Ориентация на какой-либо язык может создать новые зависимости между клиентом и компонентом. Это также обусловит трудности в дальнейшей эксплуатации клиента и компонента в случае перехода разработчиков на новые языки программирования: новые компоненты нельзя будет подключить к приложению для его модернизации.
  2. Компоненты должны поставляться в двоичной форме. Так как компоненты должны скрывать язык их реализации, они должны предоставляться в скомпилированном, скомпонованном и готовом к использованию виде.
  3. Компоненты должны быть расширяемы без влияний на существующих пользователей. Новые версии компонента должны работать как со старой, так и с новой версиями приложения-клиента. Установка новой версии компонента не должна нарушать приложение, которое использует старый компонент. Однако обратная совместимость не должна ограничивать расширение компонента. Должна быть обеспечена возможность радикально изменить поведение компонента для нового приложения при обеспечении работы старого приложения.

  4. Расположение компонента в сети должно быть прозрачно (незаметно) для приложений-клиентов. Компонент и программа, которая его использует, должны работать в одном процессе, в разных процессах одной машины или на разных машинах. Клиент должен быть способен обработать удаленный компонент таким же образом, как он обрабатывает локальный компонент. Если удаленные компоненты должны обрабатываться иначе, чем локальные компоненты, клиент придется перекомпилировать всякий раз, когда локальный компонент перемещается в другое место в сети.


COM и GUID

Вы наверняка встречались с такими вот строками:

{B801CA65-A1FC-11D0-85AD-444553540000}

Это есть уникальный глобальный идентификатор (в данном примере это идентификатор документа Acrobat Reader).

При компиляции компонента для каждого public класса и интерфейса в компоненте создаются уникальные глобальные идентификаторы (GUID). Эти GUID - 128 битовые числа, которые генерируются с использованием алгоритма (придуманного самим Microsoft), гарантирующего их уникальность.

Чтобы компонент стал доступным для клиентов, он должен зарегистрироваться в операционной системе. Компонент делает это, модифицируя раздел HKEY_CLASSES_ROOT системного реестра, внося туда информацию относительно себя. Информация включает программный идентификатор (ProgID), представляющий описательное имя компонента, идентификатор класса (ClassID), его расположение и расположение библиотеки типов.

При компиляции приложения-клиента, который обращается к компоненту сервера, идентификаторы классов и интерфейсов любого объекта, которые создаёт компонент, включаются в исполняемый файл. В период выполения клиент (вместе в COM) использует информацию в реестре для вызова компонента сервера.


Создание компонента ActiveX - графической кнопки

Итак, вам нужен определённый компонент (контрол). Есть несколько путей для решения этой проблемы:

  • Найти похожий контрол в Интернете (или, к примеру, на диске).
  • Создать свой собственный!

Первый вариант достаточно прост, но имеет недостатки. Во-первых контрол обязательно чем-то вам не угодит (поверьте мне, Обязательно!). Например, вам не понравится то, что нельзя изменить цвет фона или что-то другое. Во-вторых разве можно назвать приложение "вашим", если оно целиком и полностью будет состоять из чужих компонентов? Нет. Так что остаётся второй вариант, а именно Создание своего контрола.

Для украшения своих приложений я решил создать свой контрол - кнопку, с 3-мя состояниями (не нажата и нет курсора мыши, не нажата и есть курсор, нажата). На это у меня ушёл всего навсего один день! Кстати таких компонентов в интернете очень и очень много, но мы будем создавать свой.

Шаг №1. Создание свойств и методов, которые будет поддерживать контрол.

Итак, запускаем VB6. Выбираем из меню тип приложения - ActiveX Control. Теперь перед нами пустая форма без заголовка. Лезем в меню Add-Ins и выбираем там ActiveX Control Interface Interface Wizard. (Если вы не нашли такого пункта, то выберите команду Add-In Manager. Там отметьте галочкой всё, что нужно и жмите ОК. Ну, а если у вас и там нет такого пункта, то вам нужно запустить установку VB и добавить этот Wizard). Если вы всё сделали правильно, то должно появиться окошко, в котором слева будет список доступных свойств, методов и событий, которые вы можете включить в ваш компонент. Оставляем всё, как есть и жмём Next. Далее нам предлагают создать свои собственные события, свойства или методы. Нажмите на кнопку New. В поле Name наберите MouseOut, а в поле Type - Event. Таким образом мы создали новое событие MouseOut. Теперь нам необходимо создать свойства NormalState, DownState, OverState. Можно ещё добавить метод About (если хотите). Жмём 2 раза Next. Теперь нам нужно задать тип созданных нами свойств и методов. Для свойств NormalState, DownState, OverState выбираем тип Picture и в списках RunTime и DesignTime выбираем Read/Write (т.е. свойство доступно и для чтения, и для записи). Для метода ставим ReturnType в Empty. Всё, создание каркаса закончено, можно приступать к программированию!

Шаг №2. Программирование нашего компонента.

Вот мы и дошли до самого главного - программированию контрола. Этот процесс исключительно творческий, поэтому каждый человек пишет код по разному. Также прошу понять, что приведённый мною код НЕ является самым правильным и корректным, вы вполне можете написать лучше чем у меня.

Теперь создадите 3 Image. В них будут храниться наши рисунки для разных состояний кнопки. Назовите из соответственно imgNormalState, imgDownState, imgOverState. В них загрузите картинки, соответстующие разным состояниям кнопки. Я наваял в PhotoShop три картинки, которые вы можете взять тут.

Нам понадобятся 3 API ф-ции Windows. Вот их определения:

Private Declare Function SetCapture Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function GetCapture Lib "user32" () As Long

Первая устанавливает обработку события мыши на компонент. Вторая возвращает обработку в обычное состояние. Третья возвращает Handle элемента управления, для которого в данный момент определён SetCapture.

Вы скажете: "А нафига нам эти ф-ции? Чё, нельзя было обойтись стандартными - бейсиковскими???". Нельзя. Подумайте, как вы будете определять событие MouseOut? То-то. А при помощи этих ф-ций событие MouseMove будет происходить даже тогда, когда курсор мыши будет находится за пределами элемента управления! И следовательно мы легко можем определить событие MouseOut.

Теперь объявите переменную bstate, которая будет хранить Boolean значение. (находится над кнопкой курсор, или нет).

Dim bstate As Boolean

Здесь необходимо напомнить, что свойства в UserControl (т.е. в нашем компоненте) задаются и читаются с использованием разных процедур Set и Get. Вообще об этом можно написать целую страницу, но мы не будем вдаваться в подробности - сейчас главное - суть. Теперь найдите в коде реализацию процедуры Set NormalState. Она выполняется всякий раз, когда мы изменяем свойство NormalState UserControl'a. Нам необходимо добавить в конце вот такие строчки:

Picture = NormalState 'Положить на фон UserControl'a картинку
'определённую только что определённым свойством NormalState
imgNormalState = New_NormalState 'назначить эту же картинку для Image

В процедуры Set DownState и Set OverState добавьте соответственно строчки:

imgDownState.Picture = New_DownState

imgOverState.Picture = New_OverState

Теперь найдите обработчик события UserControl_InitProperties. В нём задаются начальные свойства (как у формы событие Load). Добавьте вот такую строчку:

UserControl.Picture = imgNormalState 'Задаём начальную картинку

В обработку события MouseDown UserControl'a добавьте строчки:

RaiseEvent MouseDown(Button, Shift, X, Y) 'запуск события MouseDown
'которое будет происходить, когда наш компонент уже будет находиться
'на использующей его форме
UserControl.Picture = imgDownState 'Изменяем картинку на DownState
bstate = True 'Устанавливаем переменную bstate

В событие MouseUp добавьте:

RaiseEvent MouseUp(Button, Shift, X, Y) 'То же самое, что и выше
UserControl.Picture = imgNormalState 'Изменяем картинку на NormalState
bstate = False 'Устанавливаем переменную bstate
RaiseEvent Click 'запускаем событие Click

Для обработки события Show UserControl'a я приготовил такой вот код (он сработает сразу тогда, когда пользователь поместит элемент на форму):

imgNormalState = NormalState
imgOverState = OverState
imgDownState = DownState
'загружаем умолчательные картинки в Imag'ы
'(т.е. те которые я создавал в PhotoShop)
UserControl.Picture = imgNormalState 'Отображаем на UserControl'e
'картинку NormalState

Кстати здесь необходимо заметить, что в VB есть умолчательные свойства. Для разных элементов они разные. Например, у Label - это Caption, у Text - Text, а у Image - Picture. Поэтому я могу сразу поставить знак равенства и присвоить значение.

А сейчас найдите обработку WriteProperties UserControl'a и замените строчку:

эту:
Call PropBag.WriteProperty("NormalState", m_NormalState, Nothing)

на вот эту:
Call PropBag.WriteProperty("NormalState", m_NormalState, _
imgNormalState)

Таким образом, мы задали умолчательное свойство для переменной m_NormalState, хранящей значение свойства NormalState.

Теперь осталась самая трудная задача - обработка события MouseMove. Вот предложенный мною код (без отступов разобраться очень сложно, поэтому я советую посмотреть этот код в исходнике кнопки):

Private Sub UserControl_MouseMove (Button As Integer, _
Shift As Integer, X As Single, Y As Single)

If bstate <> True Then
RaiseEvent MouseMove(Button, Shift, X, Y)
Dim k, ret As Long
If GetCapture() <> UserControl.hwnd Then
ret = SetCapture(UserControl.hwnd)
End If
If (X < 0) Or (Y < 0) Or (X > UserControl.ScaleWidth) Or _
(Y > UserControl.ScaleHeight) Then
RaiseEvent MouseOut
If UserControl.Picture <> imgNormalState Then
UserControl.Picture = imgNormalState
End If
ret = ReleaseCapture()
Else
If UserControl.Picture <> imgOverState Then
UserControl.Picture = imgOverState
End If
End If
Else
If (X < 0) Or (Y < 0) Or (X > UserControl.ScaleWidth) Or _
(Y > UserControl.ScaleHeight) Then
RaiseEvent MouseOut
If UserControl.Picture <> imgNormalState Then
UserControl.Picture = imgNormalState
End If
bstate = False
End If
End If

End Sub

Этот код очень прост, несмотря на кажущуюся сложность. Вкратце могу сказать, что сначала мы проверяем не установлена ли уже обработка событий мыши для UserControl'a. Если нет - то устанавливаем. После установки в обработку события MouseMove передаются и отрицательные координаты (т.е. когда мышь выходит за пределы UserControl'a слева или сверху). Далее идёт проверка этих координат на предмет наступления MouseOut. После возвращаем стандартный обработчик ф-цией ReleaseCapture.

Важно: не забудьте включить AutoRedraw у UserControl'a, а то кнопка будет подмигивать при нажатии.

Ну вот и всё!!! Теперь для тестирования можете добавить ещё один проект типа Standart EXE. Активизируйте, а затем закройте форму UserControl'a. Если этого не сделать, то вы не сможете поместить элемент на форму добавленного проекта.

Итак, поместите только что созданный элемент на форму и запустите проект. Если вы всё сделали правильно, то контрол должен работать. Можете поэкспериментировать, загружая другие картинки. КОНТРОЛ Я ПРАКТИЧЕСКИ НЕ ТЕСТИРОВАЛ, так что вы можете найти кучу багов (если найдёте - напишите мне).

Да, ещё можете изменить иконку, которая появляется на панели элементов. Для этого необходимо загрузить bitmap картинку в свойство ToolBoxBitmap размером 16x15 пикселей.

Исходники кнопки можно загрузить здесь.


Flash и Visual Basic

Macromedia Flash - одна из лучших программ, предназначенных для создания интерактивных фильмов и размещения их в Интернете. Для просмотра Flash роликов в браузере необходим ActiveX компонент. Также их можно просматривать и в отдельной программе - Stand Alone Flash Player. Но вы скажете: "А причём здесь Visual Basic?". А Visual Basic здесь может выступить в качестве контейнера для компонента ActiveX Flash! Т.е. вы можете написать свою программу на VB, в которой будет проигрываться Flash ролик! Да не просто проигрываться, а взамодействовать с программой!!! На следующей иллюстрации показана форма с загруженным Flash роликом:

После нажатия на кнопку Click ME происходит изменение Caption у формы на текст, введённый в окошке для ввода!

А теперь давайте посмотрим как это делается на самом деле.

Этап №1. Запускаем Macromedia Flash 4 (можно и 5, но я использовал четвёртый).

Создаём кнопку и текстовое поле (как это сделать - задача не этого документа). У текстового поля меняем свойство variable на "TextToVB". Далее создаём для кнопки обработчик события On_Release и вставляем такой код:

FS Command ("Hello_VB!", TextToVB)

Эта строчка посылает сообщение в программу контейнер (в нашем случае это Basic программа. Также в роли контейнера может выступать html документ и значение может быть передано коду на JavaScript). Теперь компилируем ролик в swf формат.

Этап №2. Создаём новый проект в VB. Лезем на вкладку Components... и из предложенного огромного списка ставим галочку на строчке Shockwave Flash. Теперь поместите компонент на форму. Задайте размер такой же, как и в откомпилированном ролике (в принципе, это делать не обязательно). Далее создайте кнопку на форме и вставьте в обработку клика такой код:

ShockwaveFlash1.Movie = App.Path & "\vb.swf"

Этой строчкой мы загрузим Flash фильм в компонент. При этом vb.swf должен находится в том же каталоге, где и exe файл программы. Теперь самое интересное. Создайте обработчик ShockwaveFlash1_FSCommand. Код в этом обработчике будет выполняться всякий раз, когда Flash фильм запускает команду FS Command. В нашем ролике она выполняется при щелчке мышкой на кнопке Click ME. В обработчик ShockwaveFlash1_FSCommand передаются 2 параметра: имя команды и параметры. В нашем случае имя - "Hello_VB!", а параметр - текст, введённый в текстовое поле. Итог:

Private Sub ShockwaveFlash1_FSCommand _
(ByVal command As String, ByVal args As String)
Form1.Caption = command & " : " & args
End Sub

Откомпилируйте и запустите программу. Понажимайте на копку Click ME. Вот и всё. Это был очень простой пример взаимодействия Flash и VB. Никто вам не запрещает создавать более сложные и интересные вещи! Творите!

Файлы для скачивания:

  1. Пример, использованный в этой статье
  2. ActiveX компонент Shockwave Flash 5.


Базы данных в Visual Basic. Введение.

Что такое база данных?

База данных - это совокупность данных, которая предназначена для машинной обработки и служит для удовлетворения нужд многих пользователей.

Обычно под базой данных (БД) понимается некоторым образом упорядоченный набор унифицированной информации. Предположим у нас есть телефонная книга (это, кстати, классический пример), в которой находится информация обо всех абонентах телефонной станции. Естественно, в этом случае информация будет представлена в виде регулярной структуры, например, с помощью вот такой таблицы:

Абонемент | Телефон | Адрес
.......... | .......... | ..........
Иванов С.И. | 22-11-44 | ул. Куприянова 22-44
Сидоров И.И. | 33-24-91 | пр. 50 лет октября 12-102
.......... | .......... | ..........

Как видно информация состоит из набора строк и столбцов. Для каждого абонента выделена отдельная строка, называемую записью (record). Каждый столбец называется полем (Field). Таким образом вся информация хранится в виде двумерной таблицы. На пересечении строк и столбцов расположены элементы данных, в которых, собственно, и хранится информация.

При работе с такими таблицами часто возникают вопросы, связвнные с поиском информации, её сортировкой и т.д. Эти вопросы рассмотрены в разделе Примеры работы с БД.


Работа с БД через элемент Data

Элемент управления Data в Visual Basic обеспечивает возможность формировать мощные и разнообразные приложения базы данных с очень небольшим объемом программирования.

Доступ к данным с помощью элемента управления Data

Элемент управления Data реализует доступ к данным с использованием процессора базы данных Microsoft Jet. Эта технология обеспечивает доступ к базам данных многих форматов.

Процесс создания приложения базы данных с применением элемента управления Data включает следующие два шага:

  1. Добавить элемент управления Data к форме и установить свойства, специфицирующие базу данных и таблицу, из которой будут отбираться данные.
  2. Добавить к форме связанные элементы управления и установить их свойства, чтобы связать их с элементом управления Data; после этого в них могут отображаться данные.

Использование связанных элементов управления

После размещения связанного элемента управления в форме и установки его свойств в этом элементе управления автоматически отображаются данные из базы данных. Если пользователь изменяет данные в связанном элементе управления, эти изменения автоматически фиксируются в базе данных, когда пользователь перемещается на другую запись. С данными может быть связан ряд встроенных элементов управления Visual Basic, включая флажок (CheckBox), образ (Image), надпись (Label), изображение (PictureBox), текстовое поле (TextBox), простой список (ListBox), поле со списком (ComboBox) и OLE-контейнер.

На следующей иллюстрации показана примерная форма, которая содержит элемент управления Data и два связанных элемента управления:

Некоторые свойства и методы элемента управления Data

Свойство Connect

Свойство Connect определяет тип базы данных, которую требуется открыть. Это свойство может включать такие параметры домена защиты, как идентификатор пользователя и пароль.

Свойство Exclusive

Свойство Exclusive определяет, получит ли пользователь исключительное право доступа к базе данных. Если свойство Exclusive установлено в True и затем пользователь успешно открывает базу данных, никакое другое приложение не сможет открыть базу данных, пока она не будет закрыта данным пользователем.

Свойство Readonly

Свойство Readonly определяет, может ли пользователь модифицировать базу данных. Если модифицировать базу данных не планируется, более эффективно будет установить свойство Readonly в True.

Свойство Recordset

Свойство Recordset — объект, который содержит набор записей, возвращенных элементом управления Data. С этим свойством связаны свойства и методы, которые можно использовать при работе с возвращенными записями.

Свойства BOFAction и EOFAction

Эти свойства определяют, какое действие должен выполнить элемент управления Data, когда свойства BOF или EOF набора записей принимают значение True.

Например, если свойство EOFAction элемента управления Data установлено в vbAc-tionAddNew и элемент управления Data используется для перемещения ниже последней записи набора записей, будет автоматически выполнен метод AddNew, позволяющий вводить новую запись.

Метод Refresh

Метод Refresh регенерирует объект Recordset. Если в период выполнения изменяется свойство RecordSource, необходимо вызвать метод Refresh, чтобы обновить набор записей. В следующем фрагменте показано, как использовать метод Refresh:

Data1.RecordSource = "SELECT * FROM Employees " & _
 "WHERE [Employee ID] = " & txtEmpID.text
Data1.Refresh

Объект Recordset

В приложении базы данных пользователи перемещаются по записям базы данных, используя кнопки элемента управления Data. Ниже показано, что "скрывается" за элементам управления Data и его кнопками.

Что такое Recordset?

Объект Recordset — весь набор записей, к которым обращается элемент управления Data. Набор записей хранится в памяти, в случае необходимости выгружаясь на диск.

Для манипулирования набором записей используется свойство Recordset элемента управления Data. Одна запись набора Recordset является текущей. Информация из текущей записи отображается в связанных элементах управления. Позицию текущей записи можно изменить, щелкнув кнопку элемента управления Data или программно в коде с помощью методов объекта Recordset.

Определение границ набора записей

Если для изменения позиции текущей записи используется программный код, необходимо определить начало и конец набора записей, контролируя свойства EOF и BOF объекта Recordset. При перемещении к записи EOF или BOF выполняется действие, установленное значением свойства BOFAction или EOFAction.

Например, можно установить EOFAction таким образом, чтобы автоматически добавлялась новая запись. Если свойство EOFAction установлено к EOF, то при перемещении к записи EOF никакого действия выполняться не будет. В случае же перемещения на одну запись до BOF или после EOF возвращается ошибка выполнения.

На следующей таблице показано, как свойства BOF и EOF определяют границы объекта Recordset (набора записей).

Ошибка
BOF или действие BOF
1 | Волков
2 | Глухов
3 | Данилец
... | ...
n | Степанков
EOF или действие EOF
Ошибка

Использовать объект Recordset определенного элемента управления Data в программном коде можно через свойство Recordset элемента управления Data, как показано в следующем фрагменте:

Data1.Recordset.MoveNext ' Перемещение на следующую запись набора
If Data1.Recordset.EOF Then Data1.Recordset.MoveLast

Свойства и методы объекта Recordset

Для отбора информации из набора записей используются свойства и методы объекта Recordset. Они позволяют перемещаться по записям, добавлять, модифицировать или удалять записи.

Свойства BOF и EOF

Свойства BOF и EOF объекта Recordset указывают, установлена ли позиция текущей записи в наборе перед первой записью или после последней записи. Если в наборе записей не имеется никаких записей, то и свойство BOF, и свойство EOF — True.

Метод AddNew

Добавить новую запись к набору записей можно методом AddNew. При выполнении метода AddNew Visual Basic очищает связанные элементы управления и устанавливает для свойства EditMode элемента управления Data значение dbEditAdd.

Новая запись не будет добавлена к базе данных, пока не будет явно выполнен метод UpdateRecord или Update или пока пользователь не переместится на другую запись.

В следующем фрагменте показано, как добавить новую запись к набору:

Sub cmdAdd_Click ()
Data1.Recordset.AddNew

Метод UpdateRecord элемента управления Data

Для сохранения текущей записи в базе данных используется метод UpdateRecord. В следующем фрагменте база данных модифицируется сохранением значений текущей записи:

Sub cmdUpdate_Click ()
Datal.UpdateRecord

Метод CancelUpdate элемента управления Data

Чтобы отменить метод AddNew или Edit и обновить связанные элементы управления данными из текущего набора записей, можно использовать метод CancelUpdate.

Например, если пользователь изменил поля на форме, но еще не модифицировал их и решил отменить изменения, метод CancelUpdate отменит операцию, обновит поля оригинальными данными из набора записей и выведет на экран текущую запись.

Ниже показано, как отменить добавление или редактирование записи:

Sub cmdCancel_Click ()
Datal.CancelUpdate

Метод Delete

Для удаления записи из базы данных используется метод Delete. Удаленная запись остается текущей, пока пользователь не перемещается на другую запись, как показано в следующем коде.

Sub cmdDelete_Click ()

Data1.Recordset.Delete
Data1.Recordset.MoveNext
If Data1.Recordset.EOF Then
Data1.Recordset.MoveLast
End If

End Sub

Примечание: В базе данных могут быть установлены определенные правила ссылочной целостности. Например, в базе данных Nwind установлены правила, запрещающие удаление служащих, с которыми связаны заказы. Информацию относительно управления нарушениями ссылочной целостности см. в разделе "Ссылочная целостность" главы 4 "Расширенные возможности программирования доступа к данным".


События элемента Data

Элемент управления Data поддерживает три события, которые можно использовать для расширения приложения базы данных: Validate, Reposition и Error. Эти события позволяют переопределять некоторые моменты умолчательного поведения элемента управления Data.

Событие Validate

Чтобы проверить данные до того, как запись будет сохранена в базе данных, можно использовать событие Validate. Это событие происходит непосредственно перед тем, как Visual Basic переносит изменения из связанных элементов управления в базу данных и перемещает указатель текущей записи на другую запись базы данных.

Событие Validate можно использовать для вывода пользователям запроса на подтверждение изменений.

Объявление процедуры события Validate имеет следующий синтаксис:

Private Sub Data1_Validate (Action As Integer, Save As Integer)

Параметр Action

Параметр Action указывает операцию, которая обусловила событие Validate. Событие Validate может произойти в результате одной из следующих операций:

  • метод MoveFirst, MovePrevious, MoveNext, MoveLast;
  • метод AddNew;
  • метод Update;
  • метод Delete;
  • метод Find;
  • установка свойства Bookmark;
  • закрытие базы данных;
  • вызгрузка формы.

Чтобы отменить эти действия, нужно установить для параметра Action значение vbDataActionCancel.

Параметр Save

Параметр Save указывает, изменены ли связанные данные. Если Save — True, связанные данные были изменены. Чтобы отменить сохранение, можно установить Save в False. В следующем фрагменте кода у пользователя запрашивается подтверждение изменений в базе данных. Если пользователь отвечает Нет, изменения отменяются.

Private Sub Data1_Validate (Action As Integer, Save As Integer)

Dim
        iResponse As Integer
If Save = True Then
iResponse = MsgBox ("Сохранить изменения?", vbYesNo)
If iResponse = vbNo Then
        Save = False
Data1.UpdateControls ' Восстановить значения полей
End If
End If

End Sub

Событие Reposition

Событие Reposition используется для изменения вида формы или выполнения некоторых действий при перемещении к новой записи.

Это событие происходит, когда Visual Basic перемещает указатель текущей записи на другую запись в базе данных либо при первоначальном открытии базы данных.

В следующем фрагменте показано, как вывести на экран номер текущей записи с использованием свойства AbsolutePosition объекта Recordset:

Private Sub Data1_Reposition()
Data1.Caption = "Запись № " & Data1.Recordset.AbsolutePosition + 1
End Sub

Когда пользователь перемещается на новую запись, используя элемент управления Data, может потребоваться отображать данные в формы по-разному, в зависимости от конкретных значений текущей записи.

Например, в форме для работы с записями служащих могут по-разному отображаться данные для постоянных служащих, подрядчиков, служащих со сдельной оплатой или служащих с окладом. Чтобы задействовать выбор правильного режима отображения для каждой записи, можно поместить соответствующий код в событие Reposition.

В следующем фрагменте событие Reposition используется для изменения состояния формы:

Private Sub Data1_Reposition()

Data1.Caption = Datal.Recordset.AbsolutePosition
If Data1.Recordset("EmployeeID") > 5 Then ' Если № служащего > 5
Option1.Value = True ' Служащий - руководитель
Else
Option2.Value = True ' Иначе, служащий - подчиненный
End If
Data1.Caption = "Запись № " & Data1.Recordset.AbsolutePosition + 1

End Sub

Форма, содержащая эту процедуру, выглядит следующим образом:

Событие Error

Событие Error возникает, когда пользователь взаимодействует с элементом управления Data и происходит ошибка доступа к данным. Для добавления к элементу управления Data обработки ошибок можно использовать событие Error.

Например, если пользователь изменяет поле и затем щелкает кнопку элемента управления Data, чтобы переместиться к следующей записи, элемент управления Data модифицирует текущую запись. Если в течение модификации имеет место ошибка доступа к данным, происходит событие Error.

После того как произошла ошибка, значения в связанных полях не будут изменяться. Пользователь может исправить значения и затем щелкнуть элемент управления Data, чтобы попытаться модифицировать запись снова.

Вывод на экран сообщения об ошибке

Если к событию Error не добавлен код обработки ошибок и, когда пользователь взаимодействует с элементом управления Data, возвращается ошибка, Visual Basic выведет на экран сообщение об ошибке и продолжит выполнение приложения.

Если требуется подавить вывод стандартного сообщения об ошибке, можно установить параметр Response процедуры Еггог() в ноль и выводить на экран пользовательское сообщение об ошибке, как показано в следующем фрагменте:

Private Sub Data1_Error(DataErr As Integer, Response As Integer)

If DataErr = 3022 Then ' Дублирование ключевого значения - ошибка
MsgBox "Введите уникальный номер служащего"
txtEmpID.SetFocus
Response = 0
Else
Response = 1 ' Вывести стандартное сообщение
End If

End Sub


Использование связанных элементов управления ActiveX

В дополнение к встроенным связанным элементам управления, Visual Basic обеспечивает ряд подключаемых связанных элементов управления ActiveX.

Элемент управления DBGrid

Элемент управления связанная сетка (DBGrid), в отличие от многих других связанных элементов управления, позволяет пользователям приложения базы данных просматривать и редактировать одновременно несколько записей.

Вывод на экран нескольких записей

DBGrid — элемент управления ActiveX, в котором на экран выводится ряд строк и столбцов, представляющих записи и поля из объекта Recordset. Когда свойство DataSource элемента управления DBGrid ассоциируется с элементом управления Data, элемент управления DBGrid автоматически заполняется данными; заголовки столбцов будут взяты из структуры полей набора записей.

Чтобы подключить элемент управления DBGrid к проекту:

  1. В меню Project выбрать Components.
  2. Во вкладке Controls окна диалога Components (см. рис. 1.3) выбрать Microsoft Data Bound Grid Control и нажать OK или Apply.

Пользователи могут установить фокус на отдельные ячейки и редактировать данные непосредственно в ячейке. Можно также выбрать все строки или ячейки (щелкнув заголовок столбца). Во время разработки можно установить ширину столбца и высоту строки. Кроме того, для пользователей можно установить запрет изменять форматирование в период выполнения.

В период выполнения текущую ячейку в сетке определяют свойства Row и Col. Текущую ячейку можно указать в программном коде, либо пользователь может изменить ее, используя мышь или клавиши курсора. Когда пользователь изменяет текущую ячейку, указатель записи соответствующего элемента управления Data автоматически перемещается к записи, содержащей выбранную ячейку.

Ячейки можно отредактировать в интерактивном режиме, вводя данные в ячейку либо программным способом, изменяя свойство Value текущего объекта Column (см. ниже).

Будучи создан, элемент управления DBGrid содержит единственный столбец и единственную строку. В нем также имеется пустая строка, обозначенная звездочкой (*), которая используется для добавления новых записей.

Окно свойств содержит свойства элемента управления DBGrid в целом; элемент управления можно перемещать и устанавливать по размеру. Чтобы установить свойства для отдельных объектов Column, необходимо щелкнуть элемент управления правой кнопкой мыши и выбрать Edit из контекстного меню. Используя контекстное меню, можно вставлять или удалять столбцы или вырезать и вставлять их через буфер обмена. Можно также создать столбец и скрыть его, назначив для него нулевую ширину.

Элемент управления DBGrid имеет несколько свойств, определяющих его поведение. Например, если в True установлено свойство AllowUpdate, пользователь может изменять данные в элементе управления. Свойства можно установить также для отдельных столбцов.

Чтобы установить свойства столбца:

  1. Щелкнуть элемент управления DBGrid правой кнопкой мыши.
  2. В контекстном меню выбрать Properties.
  3. В окне диалога Property Pages открыть вкладку Columns.

Здесь можно изменить заголовок столбца, назначить связанное поле данных, установить значение по умолчанию и так далее.

Чтобы установить заголовки столбцов элемента управления DBGrid, нужно во время разработки щелкнуть элемент управления правой кнопкой мыши и в контекстном меню выбрать Retrieve Fields.

Получение и установка содержимого текущей ячейки

Для получения значения выбранной ячейки в период выполнения используется семейство Columns элемента управления DBGrid. Например:

MsgBox DBGrid1.Columns(DBGrid1.Col).Text

Чтобы изменить информацию в элементе управления DBGrid, следует изменить ассоциированный объект Recordset. Например, если элемент управления DBGrid связан с набором записей элемента управления Data1, потребовалось бы выполнить следующий код:

Data1.Recordset.Edit
Data1.Recordset.Fields("Product Name") = "Монитор"
Data1.Recordset.Update

Использование события BeforeUpdate

Событие BeforeUpdate происходит перед тем, как данные перемещаются из элемента управления DBGrid в буфер элемента управления Data. В случае необходимости можно либо подтвердить, либо отменить модификацию данных.

Элемент управления MSFIexGrid

Элемент управления MSFIexGrid обеспечивает дополнительные возможности при табличном представлении данных. Он подобен элементу управления DBGrid; однако, будучи связан с элементом управления Data, элемент управления MSFIexGrid отображает на экране данные только для чтения.

Подключить элемент управления MSFIexGrid к проекту можно через окно диалога Components (меню Project | Components).


Примеры работы с БД

Почти все примеры написаны с использованием языка запросов SQL. Этим запросам посвящена глава SQL запросы. Количество примеров не очень большое, потому что здесь собрано только то, с чем я сам сталкивался при написании программ. Параметры базы данных, используемой в примере:

  • База данных mdb (Microsoft Access)
  • Подключение через элемент Data
  • Имя таблицы в базе данных: Телефоны
  • Тип соединения: Dynaset
  • Имя первого стобца: Фамилия
  • Имя второго: ID
  • Имя третьего: Телефон

Примеры

ПРОСТО ПОИСК С ПЕРЕХОДОМ НА НАЙДЕННУЮ ЯЧЕЙКУ
Data1.Recordset.FindNext "[Фамилия] = 'Иванов'"
If Data1.Recordset.EOF = True Then Data1.Recordset.MoveLast

СМЕНА ЗНАЧЕНИЯ В ЯЧЕЙКЕ
Data1.Recordset.Edit
Data1.Recordset![Телефон] = "2-22-22"
Data1.Recordset.Update

ДОБАВИТЬ ЗАПИСЬ
Data1.Recordset.AddNew
Data1.Recordset![Фамилия] = "Новый чувак"
Data1.Recordset![Телефон] = "2-15-65"
Data1.Recordset.Update

ПОИСК ПО КРИТЕРИЮ
Data1.RecordSource = "SELECT * FROM Телефоны WHERE [Фамилия] _
LIKE 'Ива*'"
Data1.Refresh

ПОИСК С ДИРЕКТИВОЙ BETWEEN
Data1.RecordSource = "SELECT * FROM Телефоны WHERE [Фамилия] _
BETWEEN 'Волков' AND 'Тарабрин'"
Data1.Refresh

СОРТИРОВКА ДАННЫХ ПО ОПРЕДЕЛЁННОМУ ПОЛЮ
Data1.RecordSource = "SELECT * FROM Телефоны ORDER BY [Фамилия] _
ASC" 'или вместо ASC - DESC (тогда по убыванию)
Data1.Refresh

ПОИСК ЗАПИСЕЙ С НУЛЕВЫМИ ЗНАЧЕНИЯМИ
Data1.RecordSource = "SELECT * FROM Телефоны WHERE [Фамилия] IS NULL"
Data1.Refresh

ПРОВЕРИТЬ, НАЙДЕНО ЛИ ЧТО-ЛИБО, ЕСЛИ НЕ НАЙДЕНО, ТО
ОТОБРАЗИТЬ ВСЕ ЗАПИСИ

If Data1.Recordset.RecordCount = 0 Then
MsgBox "Таких записей нет! Показываю все!'", vbCritical, _
"Результаты SQL запроса"
Dim recAllRecords As Recordset
Set recAllRecords = Data1.Database.OpenRecordset("Телефоны")
Set Data1.Recordset = recAllRecords
End If


SQL запросы

В этом разделе я бы хотел дать краткий справочник по операторам SQL, которые можно с успехом использовать в VB. Итак, начнём.

Все операции с данными в БД выполняются с помощью операторов SQL (SQL statement). Если работать через элемент Data, то для выполнения оператора SQL необходимо присвоить свойству RecordSource строку, содержащую запрос и затем обновить БД. Вы можете скачать пример (10Кб), в котором уже есть база дынных для примера (используется база данных Microsoft Access 2000). Информация отображается в компоненте DBGrid.

Вот список операторов SQL (не всех конечно, но самых необходимых):

===SELECT и FROM===

Оператор SELECT используется для извлечения информации из БД. Он состоит из директивы SELECT за которым через запятую перечисляются поля, из которых должна быть выведена информация. После них обязательно следует оператор FROM, который указывает на таблицу в БД. Например:

"SELECT Телефон,Фамилия,Код FROM Телефоны"

В этом примере на экран будут выведены 3 столбца в порядке, указанном в запросе. Здесь и далее можно употреблять вместо точных названий звёздочку. К примеру

"SELECT Телефон,Фамилия,Код FROM *"

==ORDER BY===

Для упорядочивания данных в столбце по возврастанию или убыванию используется опрератор ORDER BY. В следующем примере происходит сортировка по возрастанию в столбце Фамилия:

"SELECT * FROM Телефоны ORDER BY [Фамилия] ASC" _
'или вместо ASC поставить DESC (тогда по убыванию)

===DISTINCT===

Чтобы исключить дублирующие значения в столбце, используется оператор DISTINCT. Например:

"SELECT DISTINCT Фамилия FROM Телефоны"

===Булевские операторы===

В SQL допустимы стандартные булевские операторы, такие как =, >, <, <>, <=, >=. Также можно использовать комбинации этих операторов через AND, OR или XOR. Пример:

"SELECT * FROM Телефоны _
WHERE ([ID] < 3000) AND ([Фамилия] LIKE 'Вол*')"

===IN===

Этот оператор позволяет использовать множество в качестве условия отбора значений. Например, следующий запрос выведет абонентов, у которых номера телефонов 2-22-22 и 2-27-22.

"SELECT * FROM Телефоны WHERE [Телефон] IN ('2-22-22','2-27-22')"

===BETWEEN===

В отличие от предыдущего оператора, этот позволяет указать диапазон значений для выбора. В следующем примере будут выведены все записи, в которых поле ID больше 2000 но меньше 5000.

"SELECT * FROM Телефоны WHERE [ID] BETWEEN 2000 AND 5000"

===LIKE===

Этот оператор применяется исключительно к полям строкового типа. Он позволяет выбрать записи по указанной маске. Например:

"SELECT * FROM Телефоны WHERE [Телефон] LIKE '2-2*'"

===IS NULL===

С помощью этого оператора можно отобразить записи, которые содержат пустые поля. В следующем примере создаётся новая запись, в которой поле ID не задано и оператор SQL выведет на экран эту запись:

Data1.Recordset.AddNew
Data1.Recordset![Фамилия] = "Новый абонент"
Data1.Recordset![Телефон] = "2-15-65"
Data1.Recordset.Update
Data1.RecordSource = "SELECT * FROM Телефоны WHERE [ID] IS NULL"
Data1.Refresh

===Агрегатные функции===

Существуют несколько ф-ций для работы над группой выбранных полей:

COUNT - подсчёт строк, полученных в ходе запроса
SUM - сумма значений выбранного поля
AVG - среднее арифметическое поля
MAX - выводит наибольшее значение из поля
MIN - выводит наименьшее значение из поля

Пример:

"SELECT SUM(ID),MAX(ID),COUNT(Фамилия) FROM Телефоны"

===GROUP BY===

Этот оператор используется для группировки нескольких полей. Пример:

"SELECT Телефон,COUNT(ID) FROM Телефоны GROUP BY Телефон"

===AS===

Чтобы изменить имя поля используется оператор AS. В следующем примере изменяется имя поля ID на имя Идентификатор:

"SELECT Код,Фамилия,ID AS [Идентификатор],Телефон FROM Телефоны"

===Добавление выражений===

В результат запроса можно добавлять арифметические выражения. В них допустимо использование операций +, -, *, /. Например, для того чтобы вывести таблицу с удвоенным полем Id нужно:

"SELECT Код,Фамилия, Id*10, Телефон FROM Телефоны"

При выполнении этого запроса произойдёт смена имени поля Id на Expr1002. Для того, чтобы изменить имя можно использовать оператор AS:

"SELECT Код,Фамилия, Id*10 AS 'Id*10', Телефон FROM Телефоны"


Полезные советы #1

В этом разделе помещено несколько советов для программистов на Visual Basic.

  1. Если вам необходимо поменять Boolean значение на обратное, то можно использовать такой код:

    blnVal = Not(blnVal)

    Вместо такого:

    If blnVal = False Then
    blnVal = True
    Else
    blnVal = False
    End If

  2. Чтобы заменить несколько символов в строке, можно использовать функцию Mid$:

    Dim a As String
    a = "Иванов"
    Mid$(a, 1, 4) = "Петр" 'переменная a содержит "Петров"

  3. Если вы выводите в Label'e номер версии программы, а версия меняется после каждой компиляции, то в таком случае можно использовать свойства объекта App
    App.Revision
    App.Minor
    App.Major

  4. Если вам нужно добавить к строке символ перевода строки (Chr(13)+Chr(10)), то можно воспользоваться встроенной константой vbNewLine. Например

    MsgBox "Первая строка" & vbNewLine & "Вторая строка"

  5. Для того, чтобы открыть файл, находящийся в том же каталоге, что и Exe файл программы, можно использовать свойство App.Path, которое содержит путь к каталогу с программой. Пример:

    Picture1.Picture = LoadPicture (App.Path _
    & "\background.bmp")

  6. Если вам нужно предотвратить запуск второй копии программы, вставьте этот код в обработку Form_Load:

    If App.PrevInstance = True Then End

  7. Для получения списка всех доступных шрифтов в системе используйте свойство Fonts объекта Screen. Например следующий код выводит список всех шрифтов в список:

    For c = 1 To Screen.FontCount
    List1.AddItem Screen.Fonts(c)
    Next c

    Если вам нужно отсортировать этот список по имени, установите свойство ListBox'а Sorted в True.

  8. Если вы хотите использовать технологию Drag&Drop для перетаскивания файлов из проводника Windows на форму (или другой объект, поддерживающий эту технологию), то установите свойство OleDropMode в Manual, а в обработку события OLEDragDrop вставьте примерно такой код:

    Private Sub Form_OLEDragDrop(Data As DataObject, _
    Effect As Long, Button As Integer, Shift As Integer, _
    X As Single, Y As Single)

    Dim c As Long
    c = 1
    On Local Error GoTo ErrEnd
    If Data.GetFormat(15) = True Then
    Do
    List1.AddItem Data.Files(c)
    c = c + 1
    Loop
    End If
    ErrEnd:

    End Sub

  9. Совет всем программистам: придерживайтесь нижеприведённой схемы именования переменных, констант и названий функций и процедур:

    Тип
    Схема именования
    Пример
    Константа
    Имя константы должно состоять только из заглавных букв.
    HWND_BROADCAST
    Переменная
    Имя переменной должно начинаться с маленькой буквы, далее следующий слова с большой.
    numOfFonts
    Функция
    Имя функции должно начинаться с заглавной буквы, далее следующие слова тоже с заглавной.
    SetForegroundWindow

    Придерживаясь этой схемы вы намного повысите читабельность кода. Кстати такая схема используется в API функциях Windows.


Полезные советы #2

  1. Используйте Long вместо Integer. Выйгрыша в скорости вы не получите зато можете получить распространённую ошибку:

    Dim a As Integer
    Dim     b As Integer
    Dim     c As Integer

    a = 2341
    b = 65

    c = a * b

    Получите ошибку Overflow! Это происходит потому, что a - Integer, b- Integer, и результат тоже должен быть Integer, следовательно должен находиться в диапазоне -32768 - +32768, а он равен 152165. Поэтому и происходит переполнение. Этого можно избежать с помощью функции преобразования типа CLng. Т.е. c = a * CLng(b). Или задать тип Long при определении переменной (это лучший вариант). Кстати это относится и другим типам, т.е. c(integer) = a(byte) * b(byte) ...

  2. Немного магии с операторами Or:

    If x = 0 And y = 0 Then ... можно записать так:

    If (x Or y) = 0 Then ... - это чуть побыстрее

    и Xor:

    If (x = 0 And y = 0) Or (x <> 0 And y <> 0) Then ... можно так:

    If (x = 0) Xor (y <> 0) Then .. - это тоже чуть побыстрее

  3. Если вы обращаетесь к одному и тому же элементу массива в цикле, то лучше создайте переменную и присвойте ей значение этого элемента вне цикла, а в цикле используйте эту переменную.

  4. Очень мощный (как Format) оператор Like может упростить множество операций со строками, например, вам необходимо проверить строку по маске (aka Perl Regular Expressions), например вам необходимо проверить переменную myString:

    myString = "312T-87GD-8922"

    If myString Like "###[A-Z]-##[A-Z][A-Z]-####" Then ...

    Подробнее здесь.

  5. Если у вас в цикле идёт проверка некоторых условий, например:

    If a > 1 And b = Cos(alpha) And Len(myStr) < 12 Then ...

    Вы можете применить метод сокращённой оценки:

    If a > 1 Then
    If b = Cos(alpha) Then
    If Len(myStr) < 12 Then
    ' Здесь код для выполнения когда все условия истинны
    End If
    End If
    End If

    Здесь вычисление Cos будет происходить только тогда, когда a > 1, а в первом варианте он вычисляется всегда. Также здесь важна последовательность условий - сверху помещайте условие, которое может быть верным реже чем нижние и т.д. Если цикл большой, то сразу заметите выйгрыш в скорости.

  6. Функция DoEvents ОЧЕНЬ сильно замедляет работу. Если вам необходимо вычислить большой цикл и в нём вы используете DoEvents - скорость обработки цикла упадёт в десятки раз! Поэтому лучше прибегнуть к использованию API функции GetInputState (она возвращает True если форме было послано сообщение от клавиатуры или мыши):

    Declare Function GetInputState Lib "user32" _
    Alias "GetInputState" () As Long

    For c = 1 To 100000
    temp = 2 * 2 * 2
    If GetInputState() Then DoEvents ' здесь 312 мс.
    DoEvents ' а здесь время выполнения цикла 6543 мс. !!!
    Next c

  7. Если вам необходимо прочитать содержимое файла в TextBox - воспользуётесь нижеследующим кодом:

    Text1.Text = Input$(#1, LOF(1))

  8. Если вам необходимо получить адрес переменной в памяти, используйте функцию VarPtr:

    MsgBox VarPtr (myVariable)

  9. Если вам необходимо проверить существует ли какой-либо файл, можете использовать следующую функцию:

    Function FileExist(fileName As String) As Boolean
    On Error Resume Next
    FileExist = Dir$(fileName) <> ""
    If Err.Number <> 0 Then FileExist = False
    On Error GoTo 0
    End Function

  10. Если вам необходимо обменять 2 переменных целого типа, вы можете использовать такой вот код:

    Dim a As Long, b As Long
    a = 4
    b = 7
    a = a Xor b
    b = a Xor b
    a = a Xor b

    Этот магический код действительно работает. Давайте посмотрим как:

    Для тех, кто забыл как работает оператор Xor напоминаю: Xor - это логическое исключающее сложение. Таблица для Xor выглядит таким образом:

    Операнд1 0 0 1 1
    Операнд2 0 1 0 1
    ----------------
    Результ. 0 1 1 0

    Итак проверим как же работает этот код:

    a = 4 = 0100
    xor
    b = 7 = 0111
    ------------
    a = 3 = 0011

    Теперь a содержит значение 3. Далее:

    a = 3 = 0011
    xor
    b = 7 = 0111
    ------------
    b = 4 = 0100

    И накоцен:

    a = 3 = 0011
    xor
    b = 4 = 0100
    ------------
    a = 7 = 0111

    Итог: a = 7, b = 4. ч.т.д.


Полезные советы #3

  1. Если вам необходимо присвоить строке значение без изменения её длины - используйте функцию LSet (RSet). Т.е. например:

    Dim str1 As String
    Dim     str2 As String

    str1 = "Моя длинная строка"
    str2 = "Короткая"

    LSet str1 = str2
    ' str2 = "Короткая          "

  2. Чтобы создать массив "на лету" вы можете использовать функцию Array и переменную типа Variant. Например:

    Dim a As Variant
    a = Array(244, 122, 544, 222) ' или:
    a = Array("A", "B", "C", "D")

  3. Чтобы вывести своё меню в TextBox'е без применения API, нужно отключить TextBox (установить его свойство Enabled в False), вывести меню, а затем включить его обратно. Например:

    Public Sub PopUpTextBoxMenu(txtBox As Object, _
    popMenu As Object)
    txtBox.Enabled = False
    PopupMenu popMenu
    txtBox.Enabled = True
    End Sub

    Private Sub     Text1_MouseDown(Button As Integer, _
    Shift As Integer, X As Single, Y As Single)
    If Button = vbRightButton Then
    PopUpTextBoxMenu Text1, menu1
    End If
    End Sub

  4. Если вы хотите открыть Help файл (файл с расширением .hlp) из своей программы, то можете воспользоваться функций API WinHelp:

    Const HELP_CONTENTS = &H3&

    Declare Function WinHelp Lib "user32" Alias "WinHelpA" _
    (ByVal hwnd As Long, ByVal lpHelpFile As String, _
    ByVal wCommand As Long, ByVal dwData As Long) As Long

    Public Sub     OpenHelpFile(HelpFileName As String)
    WinHelp hwnd, HelpFileName, _
    HELP_CONTENTS, 0
    End Sub

    ' Где HelpFileName - путь к Help файлу.

  5. Советы по работе в среде Visual Basic (IDE):

    Пользуйтесь горячими клавишами! Это намного ускорит процесс программирования. Вот самые полезные на мой взгляд:

    Функция IDE
    Горячая клавиша
    Запуск программы
    F5
    Поставить/Убрать точку останова
    F9
    Пошаговое выполнение программы (трассирование) с заходом в процедуры
    F8
    Пошаговое выполнение программы (трассирование) без захода в процедуры
    SHIFT+F8
    Открыть Object Browser
    F2
    Поиск/Замена
    CTRL+F
    Сделать отступ
    TAB
    Отменить отступ
    SHIFT+TAB
    Вызвать редактор меню
    CTRL + E

    Если вам часто приходиться комментировать и раскомментировать код, рекомендую вынести эти кнопки на панель. Для этого Выберите меню View, далее ToolBars, потом Customize... Появиться окно. Выберите вкладку Commands. В списке слева выберите Edit, а справа найдите команды Comment Block и Uncomment Block. теперь перетащите их куда вам нравиться, например на главный тулбар.

  6. Если у вас в программе повторяется некий кусок кода (4 или более строк) то лучше создать процедуру, в которой будут находиться эти строки, а в тех местах, где эти строки понадобяться - вставлять вызов этой процедуры.

  7. Не пользуйтесь подключаемыми ActiveX компонентами где это возможно (т.е. файлами .ocx), т.к. при переносе программы на другой компьютер вам придёться таскать эти файлы с собой.


Оптимизация объёма памяти

Ещё одной целью оптимизации может быть уменьшение объема памяти, потребляемого программой. Методы, которыми это достигается, в значительной степени противоположны методам оптимизации скорости:

  • Следует минимизировать число форм, одновременно находящихся в памяти, т. е. загружать каждую форму по мере необходимости и сразу выгружать, как только в ней отпадет нужда.
  • Следует минимизировать количество управляющих элементов на той форме, на которой их размещено больше всего.
  • Если текстовое поле используется только для вывода текста, замените его этикеткой.
  • Заменяйте, где это возможно, Variant-переменные на переменные простых типов. Например, переменная типа Variant, содержащая значение типа Integer, занимает в памяти 16 байт, в то время как переменная типа Integer—только 2 байта.
  • При использовании точечных рисунков загружайте их из графических файлов в процессе выполнения программы, а не помещайте на форму на этапе визуального программирования. Если рисунок требуется использовать многократно, загрузите его в невидимый элемент Image.

Примечание:

Данные типа Variant неоднократно уже подвергались заслуженной критике. Однако следует помнить, что гибкость Variant-переменных способна иной раз сослужить неплохую службу. Не исключено, что благодаря переменной типа Variant вам удастся реализовать такой алгоритм обработки данных, который одновременно повысит скорость, уменьшит объем потребляемой памяти и сократит «поле» для ошибок.


Оптимизация скорости

Существует 3 типа скорости:

  1. Реальная скорость программы - это скорость, с которой работает её код.
  2. Скорость работы интерфейса с той точки зрения, с которой её оценивает пользователь, выражается видимых признаках работы программы, т.е. в том, насколько быстро элементы окна приложения реагируют на действия пользователя.
  3. Субъективная скорость определяется впечатлением о скорости работы программы, которое возникает у пользователя. Многие знают, как может раздражать медленно реагирующая программа, и как приятно работать с программой, которая не заставляет себя ждать.

Мы с вами рассмотрим первый тип. Ниже я привёл данные для сравнения скорости выполнения некоторых операций. Я думаю эти данные пригодятся программистам на Visual Basic. Для сравнения времени на выполнение некоторой операции я использовал API функцию Windows - GetTickCount. Она возвращает количество милисекунд (1/1000 секунды), прошедших с момента запуска Windows. Разность показаний до выполнения некоторого кода и после и будет являться временем, которое ушло на выполнение этого кода. При вычислении времени брались средние значения. Общая схема тестирования была такова: записывались 2 куска кода, затем один из них закомментировывался и вычислялась скорость работы другого куска. Затем наоборот.

Всё тестировалось на: Visual Basic 5 Ent. Ed. и машине Pentium 225 MMX с 81 RAM.

Объявление API функции:

Private Declare Function GetTickCount Lib "kernel32" () As Long

1. Возведение в степень

Dim ms As Long
Dim c As Long
Dim temp As Long
ms = GetTickCount
'================
For c = 1 To 1000000
temp = 2 ^ 8 ' 4106 мс
temp = 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ' 427 мс
Next c
'================
Form1.Caption = (GetTickCount - ms)

2. Функции Mid и Mid$

Dim ms As Long
Dim c As Long
Dim temp As String
ms = GetTickCount
'================
For c = 1 To 100000
temp = Mid("Stroka", 2, 2) ' 736 мс
temp = Mid$("Stroka", 2, 2) ' 325 мс
Next c
'================
Form1.Caption = (GetTickCount - ms)

3. Функции Left и Left$

Dim ms As Long
Dim c As Long
Dim temp As String
ms = GetTickCount
'================
For c = 1 To 100000
temp = Left("Stroka", 3) ' 550 мс
temp = Left$("Stroka", 3) ' 211 мс
Next c
'================
Form1.Caption = (GetTickCount - ms)

Вывод: используйте функции со знаком $. Функции без оного возвращают тип Variant, поэтому и работают медленнее.

4. Сравнение быстроты доступа к свойству и к переменной

Dim
    ms As Long
Dim c As Long
Dim temp As String
Dim tCapt As String
ms = GetTickCount
tCapt = Form1.Caption
'================
For c = 1 To 100000
temp = Form1.Caption ' 3640 мс
temp = tCapt ' 183 мс !!!
Next c
'================
Form1.Caption = (GetTickCount - ms)

Вывод: Когда вам нужно добраться к свойству в цикле, и которое не изменяется, то воспользуйтесь переменной! Присвойте ей значение до цикла.

5. Сравнение скорости Variant и Long перемынных

Dim ms As Long
Dim c As Long
Dim temp As Variant
ms = GetTickCount
'================
For c = 1 To 1000000
c = c ' 379 мс
Next c

For temp = 1 To 1000000
temp = temp ' 539 мс
Next temp
'================
Form1.Caption = (GetTickCount - ms)

Вывод: Там, где это возможно, используйте подходящий для операции тип. В данном случае больше всего подходит тип Long.

6. Сравнение скорости работы строк фикс. длины и строк произв. длины

Dim
    ms As Long
Dim c As Long
Dim temp1 As String * 10
Dim temp2 As String
ms = GetTickCount
'================
For c = 1 To 1000000
temp1 = "String1" & temp1
temp1 = "String2" ' 5400 мс
Next c

For c = 1 To 1000000
temp2 = "String1" & temp2
temp2 = "String2" ' 4039 мс
Next c
'================
Form1.Caption = (GetTickCount - ms)

Вывод: Строковые переменные фикс. длины медленнее, чем произвольной.

7. ="" и len(...)=0

Dim
    ms As Long
Dim c As Long
Dim temp1 As String
ms = GetTickCount
'================
For c = 1 To 1000000
If temp1 = "" Then
c = c ' 900 мс
End If

If Len(temp1) = 0 Then
c = c ' 740 мс
End If
Next c
'================
Form1.Caption = (GetTickCount - ms)

Вывод: Для проверки строк на вшивость (""), используйте функцию Len.

8. Move и изменение Left,Top,Width и Height

Dim ms As Long
Dim c As Long
ms = GetTickCount
'================
For c = 1 To 10000
Form1.Move 0, 0, 1000, 1000 ' 2545 мс

Form1.Left = 0
Form1.Top = 0
Form1.Width = 1000
Form1.Height = 1000 ' 3048 мс
Next c
'================
Form1.Caption = (GetTickCount - ms)

Вывод: Для изменения положения или размеров формы используйте метод Move, он работает быстрее, тем более при изменении отдельных свойств форма будет проскальзывать по экрану.

9. Сравнение метода PaintPicture и API ф-ции BitBlt

Dim ms As Long
Dim c As Long
ms = GetTickCount
'================
For c = 1 To 8000

Form1.PaintPicture Picture1, 0, 0, 100, 100, _
0, 0, 100, 100, vbSrcCopy ' 9102 мс

BitBlt Form1.hdc, 0, 0, 100, 100, _
Picture1.hdc, 0, 0, vbSrcCopy ' 6303 мс

Next c
'================
Form1.Caption = (GetTickCount - ms)

Вывод: API функции работают быстрее. И это факт. Так что там, где нужна скорость, на помощь приходят API функции.

Примечание: Вообще-то здесь сравнение PaintPicture и BitBlt не совсем удачно, т.к. аналогом функции PaintPicture является API StretchBlt. Но скорость её работы в данном случае такая же, как и у BitBlt.

10. Visual Basic 5 vs Borland C++ Builder 4!

Недавно я решил испробовать BC++4 на скорость, сравнив его с VB5. Результаты меня просто ошеломили! Мой брат, программирующий на BC++4 уже подумывает о переходе на VB5! Вот какие результаты я получил:

1. Скорость API функции SetPixel на заполнение формы (800x600) чёрными точками.

Код на Borland C++ 4 Builder:

WindowState
    = wsMaximized;
int
    a = GetTickCount();
for(int
    z = 0; z < 3; z++)
for(int y = 0; y < 600; y++)
for(int x = 0; x < 800; x++)
SetPixel(Canvas->Handle, x, y, 0);
Caption
    = IntToStr( GetTickCount() - a );

Код на Visual Basic 5:

Form1.WindowState = vbMaximized
Dim a, z, x, y As Long
a = GetTickCount
For z = 1 To 3
For y = 0 To 600
For x = 0 To 800
SetPixel Form1.hdc, x, y, 0
Next x
Next y
Next z
Form1.Caption = GetTickCount - a

2. Скорость вычисления синуса числа. (в VB Double, в BC++ float).

Код на Borland C++ 4 Builder:

int
    a = GetTickCount();
float b;
for(int x = 0; x < 1000000; x++)
b = sin(x);
Caption = IntToStr( GetTickCount() - a );

Код на Visual Basic 5:

Dim
    a, c As Long
c = GetTickCount
Dim b As Double
For a = 0 To 1000000
b = Sin(a)
Next a
Form1.Caption = (GetTickCount - c)

Таблица с результатами:

№ Теста | Время выполнения кода в Visual Basic | Время выполнения кода в Borland C++ Builder 4
1 | 12380! мс | 12790 мс
2 | 1440! мс | 1806 мс


Как избежать ошибок

Есть много способов решить одну и ту же задачу, но не все они одинаково удачны. Программисту, работающему над проектом в среде Visual Basic, следует учитывать ряд обстоятельств, влияющих на качество конечного продукта, и придерживаться ряда правил, позволяющих это качество повысить. Речь идет, во-первых, об ошибках в программе и о том, как их избежать.

Как избегать ошибок

  • Не жалейте времени на планирование проекта. Заранее в точности определите, что программа должна делать и как она должна себя вести. Продумайте каждое возможное событие и реакцию на него. И только после этого приступайте к созданию программы.
  • Используйте всегда, когда это возможно, явно заданные ссылки на объекты, определяемые типами Variant и Object.
  • Придерживайтесь соглашений об именах и о коде. Это особенно важно при работе над коллективным проектом.
  • Всегда помещайте оператор Option Explicit в начало любого модуля, чем избавите себя от ошибок, связанных с неверными именами переменных и управляющих элементов. Оператор Option Explicit будет автоматически помещаться в раздел глобальных объявлений каждого созданного вами модуля, если вы установите флажок Require Variable Declaration на вкладке Editor диалога Options (открывается одноименной командой меню Tools). Ниже приведён пример ошибки, являющейся следствием отстутствия оператора Option Explicit:

    Private Sub Command1_Click()
    Dim strCaption As String
    strCaption = Form1.Caption
    MsgBox strCaprion, vbCritical, "Нет Option Explicit"
    End Sub

    Назначение такого кода - вывести текущий заголовок формы Form1 в окно сообщения. Но результатом этого кода будет вот такая картина:

    Почему так? Да потому что вы допустили ошибку при написании имени переменной. Вместо strCaption вы ввели strCaprion. А Visual Basic при встрече ещё не объявленной переменной объявляет эту переменную сам, как Variant, но не присваивает ей значения. Поверьте, вы далеко не сразу обнаружите несоответствие имён. Тем более если у вас был бы большой код! Ниже изображено окошко, которое появилось бы, если бы вы вставили Option Explicit в начало программного модуля:

    И после нажатия на ОК, VB показал бы вам, где он нашёл неопределённую переменную. И вы бы уже давно писали следующий кусок кода программы, а не искали бы ошибку...


Программирование Win32API. Введение.

DLL & API

Как и всякая уважающая себя система программирования для среды Windows, Visual Basic позволяет обращаться к API-функциям, содержащимся в DLL-библиотеках. Точно так же, конечно, можно обращаться и к любым другим DLL-функциям — механизм обращения при этом не меняется.

Синтаксис объявления API-функции

Прежде чем можно будет обратиться к функции из DLL-библиотеки, ее необходимо объявить. Это делается с помощью оператора Declare, два варианта синтаксиса которого будут приведены ниже. Первый вариант относится к объявлению процедуры (DLL-функция не возвращает значения), второй — к объявлению DLL-функции, которая возвращает значение. При объявлении DLL-функций следует учитывать ряд обстоятельств:

  • Если DLL-функция объявляется с помощью оператора Declare в модуле формы, то она должна объявляться как Private. В программном модуле, напротив, DLL-функция должна объявляться, как Public.
  • Чтобы избежать конфликта имен (когда имя DLL-функции совпадает с одним из зарезервированных слов), следует использовать зарезервированное слово Alias в объявлении функции — таким образом можно задать псевдоним для DLL-функции.
  • API-функции используют типы данных языка С, поэтому параметры при вызове API функций следует задавать с учетом совместимости типов С и Visual Basic.
    Итак, вот обещанный синтаксис:

[Private/Public] Declare Sub Имяфункции Lib "ИмяDLL-файла" [Alias "Псевдоним"] [([СписокПарамегров])]

[Private/Public] Declare Function Имяфункции Lib "ИмяDLL-файла"

[Alias "Псевдоним"] [([СписокПараметров}]] As ИмяТипа

Рассмотрим каждый параметр:

  • Имяфункции. Имя функции или процедуры, под которым она будет доступна в коде Visual Basic-программы. Используют настоящие имена функций (как они определены в DLL-библиотеке) или псевдонимы, которые должны быть определены с помощью зарезервированного слова Alias.
  • ИмяDLL-файла. Имя DLL-файла библиотеки, где содержится объявляемая функция.
  • СписокПарамегров. Параметры функции или процедуры. Типы параметров должны быть совместимыми с С-типами, используемыми в API-функциях.
  • ИмяТипа. Определяет тип возвращаемого функцией значения.

Пример:

Эта ф-ция предназначена для копирования изображения с одного контекста устройства на другой.

Declare Function BitBlt Lib "gdi32" _
(ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, _
ByVal dwRop As Long) As Long


Преобразование объявлений С в типы данных Visual Basic

Обычно процедуры DLL пишутся на языке программирования C, поэтому их параметры определяются типами данных C. Когда используется оператор Declare для DLL в Visual Basic, необходимо спроецировать типы данных параметров на типы данных C.

В следующей таблице перечислены обычно используемые объявления языка C и их эквиваленты Visual Basic для 32-разрядных компиляторов:

Объявления языка C | Объявление Visual Basic | Вызов
Указатель на строку (LPSTR) | ByVal <переменная> As String | с переменной String или Variant
NULL | ByVal <переменная> As String | с константой vbNullString
char | ByVal <переменная> As Byte | с выражением, которое оценивается как тип данного Byte
integer | ByVal <переменная> As Long | с выражением, которое оценивается как тип данного Long
Дескриптор Windows (hWnd, hDC, hMenu) | ByVal <переменная> As Long | с выражением, которое оценивается как тип данного Long


Вызов DLL

При вызове процедуры DLL имеется несколько аспектов, связанных с передачей параметров. Они включают:

  • передача в процедуру DLL пустого значения;
  • выбор передачи параметров с их значением или по ссылке на это значение;
  • обеспечение в Visual Basic строк, размер которых достаточен для размещения строк С.

Передача нулевых значений

Когда процедура DLL принимает параметр с пустым значением, она ожидает нулевое значение (0) вместо пустой строки (NULL). Чтобы передать пустое значение, следует объявить параметр ByVal As String и передать константу vbNullString, как показано в следующем примере:

Declare Function FindWindow Lib "User32" Alias "FindWindowA" _
(ByVal IpClassName As String, ByVal IpCaption As String) As Long

re = FindWindow (vbNullString, "Microsoft Word")

Примечание: В Visual Basic версии 3.0 единственым способом передать пустое значение было ByVal 0&. Если использовались DLL, которые требовали строку или NULL, нужно было либо объявить параметр As Any, либо объявить DLL дважды, один раз с параметром String и второй раз — с параметром Long.

Передача параметров по значению и по ссылке

Visual Basic передает параметры процедурам по ссылке, используя 32-разрядный адрес значения данного, или по значению, используя фактическое значение переменной параметра.

По умолчанию, Visual Basic передает параметры по ссылке. Однако многие процедуры DLL ожидают, что параметры будут переданы по значению. Если параметр передается неправильно (например, если передается значение в процедуру, которая ожидает адрес), это может обусловить блокировку по общей защите.

Передача параметров по значению

При передаче параметра по значению процедуре передается копия оригинального значения данного. Если процедура изменяет значение, на оригинальную переменную это изменение не воздействует.

Чтобы передать параметр по значению, необходимо в операторе Declare перед объявлением параметра поместить ключевое слово ByVal, как показано в следующем фрагменте:

Declare Function FlashWindow Lib "User32" _
(ByVal hwnd As Long, ByVal binvert As Long) As Long

Передача параметров по ссылке

При передаче параметра по ссылке в процедуру передается адрес памяти оригинальной переменной. Если процедура изменяет значение этой переменной, оригинальное значение также изменяется.

В объявлении процедуры можно специфицировать ByVal или ByRef. Если ключевое слово не специфицируется, Visual Basic автоматически передает параметры по ссылке. Хотя включать ByRef в объявлении не требуется, текст кода будет более читабельным, если явно используется или ByRef, или ByVal.

Передача строковых значений

Строковые типы данных в Visual Basic хранятся в формате, отличном от эквивалентных типов данных языка С. Большинство DLL и все процедуры в Windows API распознают формат строки языка С. При передаче строковых значений в Visual Basic необходимо учитывать эти различия, объявляя строковые параметры по значению, принимая во внимание при этом различия в длине строковых значений.

Объявление строковых параметров по значению

Если процедура DLL ожидает в качестве параметра строку формата С, необходимо объявить параметр Visual Basic как String, которому предшествуют ключевое слово ByVal. Значение строковой переменной — это фактически указатель на область в памяти, которая содержит строку. Следовательно, процедура DLL может изменять строковую переменную Visual Basic, полученную как параметр.

Учет различий в длине строк

DLL не может увеличить длину строки Visual Basic и производит запись вне конца строки, если она недостаточно длинная. Чтобы обеспечить достаточно пространства для строки любой длины, можно использовать один из следующих методов:

Заполнить символьную строку максимальным ожидаемым числом символов:

Dim FilePath As String
FilePath = String (255, 0)

Определить строку фиксированной длины с максимально возможной длиной:

Dim FilePath As String * 255

Строки, возвращаемые процедурой DLL, в конце строки содержат символ пробела. При объединении нескольких строк потребуется удалять этот символ пробела. Так как имеются процедуры, которые возвращают целое число, указывающее длину строки, можно либо использовать функцию Left, чтобы удалить символ пробела, либо искать символ пробела, используя Chr(0).

Пример передачи строкового значения

Процедура GetWindowsDirectory используется для возвращения пути папки Windows. При этом для пути папки Windows необходимо обеспечить пустую строку достаточной длины, чтобы принять самое длинное возможное имя папки.

Процедура GetWindowsDirectory возвращает целое число, которое указывает фактическое число символов в изменяемой строке. Эта строка будет содержать NULL в качестве последнего символа. NULL можно удалить, найдя его или используя функцию Left, как показано в следующем примере:

Declare Function GetWindowsDirectory Lib "Kernel32" _
Alias "GetWindowsDirectoryA" _
(ByVal f As String, ByVal fLen As Long) As Long

Sub Commandl_Click ()

Dim sWinDir As String
Dim ILen As Long
sWinDir = String(255,0)
ILen = GetWindowsDirectory (sWinDir, Len (sWinDir))
sWinDir = Left (sWinDir, ILen)
sWinDir = sWinDir + "\"
MsgBox "Windows находится в " + sWinDir

End Sub


Процедуры обратного вызова (callback)

Процедуры обратного вызова

DLL может сообщать или давать информацию клиенту, вызывая подпрограмму, обеспечиваемую клиентом. Эта подпрограмма клиента известна как функция обратного вызова. В течение одного вызова Windows API эта функция обратного вызова может вызываться несколько раз.

Процедуры-перечисления, в которых перечисляется набор элементов, являются общим примером DLL, использующих функции обратного вызова для передачи информации клиенту.

Обратные вызовы в Visual Basic

Visual Basic позволяет создавать процедуры обратного вызова, которые обеспечивают сообщение клиенту.

Например, можно создать процедуру обратного вызова, которая будет посылать сообщение клиенту каждый раз, когда сервер выполнит некоторую операцию. Затем для вызова этой процедуры используется DLL.

На следующей иллюстрации показано, как процедуры обратного вызова работают в Visual Basic:

Передача процедуры обратного вызова к DLL

Для передачи процедуры обратного вызова к DLL Visual Basic использует операцию AddressOf. Процедура обратного вызова должна быть размещена в стандартном модуле и иметь правильный синтаксис.

Нахождение точного синтаксиса для процедуры обратного вызова может быть довольно трудной задачей, так как обычно указания на этот счет можно найти только в документации к DLL. Использование правильного синтаксиса важно, так как Visual Basic не обеспечивает контроль синтаксиса и ничего не сообщает относительно ошибок.

Примечание: Использование неправильного синтаксиса в процедуре обратного вызова наиболее вероятно обусловит в приложении фатальную ошибку в период выполнения.

При специфицировании обратных вызовов из Visual Basic следует убедиться в том, что выполнены следующие два требования:

  • функция обратного вызова должна быть размещена в стандартном модуле;
  • для передачи процедуры обратного вызова к DLL должна использоваться операция AddressOf.

Пример обратного вызова

А теперь давайте рассмотрим пример использования процедур обратного вызова для получения списка дескрипторов и заголовков всех существующих в данный момент окон. Итак, объявляем нужные API функции:

Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, _
ByVal cch As Long) As Long

Здесь первая функция используется для перечисления всех окон. В неё передаётся адрес функции-обработки. Вторая для получения заголовка окна по его дескриптору.

Поместите на форму кнопку Command и список ListBox. Теперь опишем функцию обработки EnumWindowsProc и вставим её в стандартный модуль (это обязательно).

Public Function EnumWindowsProc (ByVal hwnd As Long, _
ByVal lParam As Long) As Boolean

Dim capt As String
Dim lenC As Long
capt = String(255, " ") 'заполняем строку пробелами
lenC = GetWindowText(hwnd, capt, 255) 'получаем заголовок окна hwnd
capt = Left(capt, lenC) 'обрезаем его, оставляя только нужную часть
If capt <> "" Then Form1.List1.AddItem Str(hwnd) & " " & capt
EnumWindowsProc = True

End Function

В параметр hwnd передаётся дескриптор найденного окна. В конце обработки мы присваиваем нашей EnumWindowsProc значение True. Если этого не сделать, то функция EnumWindows больше не будет вызывать EnumWindowsProc.

Ну и наконец вставим код вызова EnumWindows в обработку клика кнопки:

Private Sub Command1_Click()
EnumWindows AddressOf EnumWindowsProc, 0
End Sub

Запустите программу и посмотрите на результат. Вы должны получить дескрипторы всех существующих в данный момент окон, содержащих заголовок.


Полезные API функции Windows

В процессе создания приложения на Visual Basic возникают ситуации, когда какое-либо действие нельзя осуществить стандартными средствами Visual Basic. Здесь на помощь приходят Windows API. Вот пример: вам необходимо узнать сколько место осталось на диске. Как это зделать с помощью VB? Никак. А с помощью Windows API - легко!

Здесь я поместил наиболее часто употребляемые ф-ции Windows API. Они расположены в алфавитном порядке.

  • BitBlt - Копирует изображение из одного hDC в другой.
  • ExitWindowsEx - Перезагрузка или выход из Windows.
  • FindWindow - Находит Handle окна с указанным Caption.
  • GetCursorPos - Возвращает текущую позицию курсора мыши (глобально).
  • GetDriveType - Возвращает тип накопителя.
  • GetForegroundWindow - Возвращает Handle активного окна.
  • SetCursorPos - Устанавливает новую позицию курсора мыши.
  • SetVolumeLabel - Изменяет метку диска.
  • SetWindowPos - Устанавливает позицию окна с определённым Handle (также с помощью этой функции можно сделать так, чтобы окно было ПОВЕРХ всех.
  • ShellExecute - Запускает приложение, ассоциированное с расширением, которое имеет указанный файл (также может просто запустить указанное приложение).
  • ShowCursor - Скрывает или показывает курсор мыши на экране.

BitBlt - Копирует изображение из одного hDC в другой.

Синтаксис объявления:

Declare Function BitBlt Lib "gdi32" Alias "BitBlt" _
(ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _
ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Пример:

Поместите на форму 2 PictureBox и загрузите в первый какую-нибудь картинку. Затем вставьте такой код:

Private Const SRCCOPY = &HCC0020

Private Sub Command1_Click()
BitBlt Picture2.hDC, 0, 0, 100, 100, Picture1.hDC, 0, 0, SRCCOPY
End Sub

ExitWindowsEx - Перезагрузка или выход из Windows.

Синтаксис объявления:

Declare Function ExitWindowsEx Lib "user32" Alias "ExitWindowsEx" _
(ByVal uFlags As Long, ByVal dwReserved As Long) As Long

Пример:

Private Sub Command1_Click()
ExitWindowsEx EWX_SHUTDOWN, 0
'Выключит компьютер. Второй параметр в ф-ции игнорируется
End Sub

FindWindow - Находит Handle окна с указанным Caption.

Синтаксис объявления:

Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Пример:

Private Sub Command1_Click()
Dim hand As Long
hand = FindWindow(vbNullString, "Калькулятор")
'hand - содержит Handle (или дескриптор) окна с заголовком Калькулятор
End Sub

GetCursorPos - Возвращает текущую позицию курсора мыши (глобально).

Синтаксис объявления:

Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" _
(lpPoint As POINTAPI) As Long

Пример:

Type POINTAPI
x As Long
y As Long
End Type

Private Sub Command1_Click()
Dim a As POINTAPI
GetCursorPos a
Form1.Caption = a.x
End Sub

GetDriveType - Возвращает тип накопителя.

Синтаксис объявления:

Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" _
(ByVal nDrive As String) As Long

Пример:

Private Sub Command1_Click()
Form1.Caption = GetDriveType("E:\")
'Возвратит 5 если это устройство CD-ROM
End Sub

GetForegroundWindow - Возвращает Handle активного окна.

Синтаксис объявления:

Declare Function GetForegroundWindow Lib "user32" Alias _
"GetForegroundWindow" () As Long

Пример:

Private Sub Command1_Click()
Dim a As Long
a = GetForegroundWindow 'a содержит Handle активного окна
End Sub

SetCursorPos - Устанавливает новую позицию курсора мыши.

Синтаксис объявления:

Declare Function SetCursorPos Lib "user32" Alias "SetCursorPos" _
(ByVal x As Long, ByVal y As Long) As Long

Пример:

Private Sub Command1_Click()
SetCursorPos 100, 100
End Sub

SetVolumeLabel - Изменяет метку диска.

Синтаксис объявления:

Declare Function SetVolumeLabel Lib "kernel32" Alias _
"SetVolumeLabelA" (ByVal lpRootPathName As String, _
ByVal lpVolumeName As String) As Long

Пример:

Private Sub Command1_Click()
SetVolumeLabel "D:\", "NewLabel"
End Sub

SetWindowPos - Устанавливает позицию окна с определённым Handle (также с помощью этой функции можно сделать так, чтобы окно было ПОВЕРХ всех.

Синтаксис объявления:

Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long

Пример:

Private Sub Command1_Click()
SetWindowPos Form1.hwnd, -1, 0, 0, 200, 200, 0
'Устанавливает форму поверх всех окон, а также перемещает её в 'указанные координаты и задаёт указанный размер (200 на 200 пикселей)
End Sub

ShellExecute - Запускает приложение, ассоциированное с расширением, которое имеет указанный файл (также может просто запустить указанное приложение).

Синтаксис объявления:

Declare Function ShellExecute Lib "shell32.dll" Alias _
"ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _
ByVal lpFile As String, ByVal lpParameters As String, _
ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Пример:

Const SW_MAXIMIZE = 3

Private Sub Command1_Click()
ShellExecute Form1.hwnd, "open", "C:\temp\1.bmp", 0, 0, SW_MAXIMIZE
'Откроет программу, ассоциированную с расширением bmp и развернёт
'её на весь экран
End Sub

ShowCursor - Скрывает или показывает курсор мыши на экране.

Синтаксис объявления:

Declare Function ShowCursor Lib "user32" Alias "ShowCursor" _
(ByVal bShow As Long) As Long

Пример:

ShowCursor 1 'Добавляет к дисплейному счёткику единицу
ShowCursor 0 'Отнимает от дисплейного счёткика единицу

Когда счётчик становится меньше нуля - курсор исчезает.


Контексты устройств

Контекст устройства (Device Context или DC) - это структура данных, содержащая физические параметры устройства и используемая для доступа к устройству. На таких контекстах можно рисовать, выводить текст, закрашивать фигуры и т.д. и т.п. В API функциях Windows есть масса функций для работы с контекстами устройств. Здесь мы остановимся на наиболее часто используемых.

CreateDC - возвращает контекст устройства, заданного имени. Следующий пример создаёт контекст дисплея (экрана):

Dim hDisp As Long
Dim dM As DEVMODE
hDisp = CreateDC("DISPLAY", 0, 0, dM)

Здесь переменная dM - типа DEVMODE. Это очень большая структура, которую необходимо включить в код.

А теперь мы используя ф-цию BitBlt скопируем на этот контекст изображение из PictureBox. Итак, поместите на форму PictureBox и загрузите туда произвольную картинку. Затем создайте кнопку и вставьте вот такой код:

Dim hDisp As Long
Dim dM As DEVMODE
hDisp = CreateDC("DISPLAY", 0, 0, dM)
BitBlt hDisp, 300, 300, 100, 100, Picture1.hdc, 0, 0, vbSrcCopy

Запустите программу и посмотрите что произойдёт.

А теперь напишем более сложную программу, которая будет выводить в PictureBox содержимое экрана под курсором. Поместите на форму PictureBox и задайте ему размеры 80 на 80 пикселей. Создайте таймер с интервалом 100 миллисекунд. Далее создайте новый модуль и вставьте в него следующие определения:

Type DEVMODE
dmDeviceName As String * 32
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * 32
dmUnusedPadding As Integer
dmBitsPerPel As Integer
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type

Type POINTAPI
x As Long
y As Long
End Type

Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) _
As Long

Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long

Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" _
(ByVal lpDriverName As String, ByVal lpDeviceName As String, _
ByVal lpOutput As String, lpInitData As DEVMODE) As Long

Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, _
ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal hSrcDC As Long, _
ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Теперь поместите в код формы код:

Dim hDisp As Long
Dim dM As DEVMODE
Dim curPos As POINTAPI

Private Sub Form_Load()
hDisp = CreateDC("DISPLAY", 0, 0, dM)
SetWindowPos Form1.hwnd, -1, Form1.Left, Form1.Top, _
Form1.ScaleWidth, Form1.ScaleHeight, 3
End Sub

Private Sub Timer1_Timer()
GetCursorPos curPos
BitBlt Picture1.hdc, 0, 0, 80, 80, hDisp, curPos.x - 40, _
curPos.y - 40, vbSrcCopy
End Sub

Запустите программу. Вы должны наблюдать, как в PictureBox отображается содержимое экрана под курсором (как в программе Microsoft Magnifier, поставляемой с Windows, только там увеличенное изображение).

Вот и всё. Желаю приятного программирования на контекстах устройств.


Работа с реестром

Работа с реестром - это одна из наиболее частых проблем, возникающих у программиста не только на Visual Basic, но и на других языках. В стандартных функциях Visual Basic нет функций для работы с реестром, но с помощью Windows API это можно устроить. Приведённые ниже примеры используют модуль registry.bas, который содержит объявления API ф-ций, констант и готовых процедур, с которыми очень удобно работать. Модуль registry.bas можно скачать.

Ф-ции чтения:

Для чтения строкового параметра используйте ф-цию GetRegString

Пример:

Dim a As String
a = GetRegString(HKEY_LOCAL_MACHINE, _
"Software\Microsoft\DirectX", "Version")
Form1.Caption = a

Для чтения параметра DWORD используйте ф-цию GetRegDWord

Пример:

Dim a As Long
a = GetRegDWord(HKEY_LOCAL_MACHINE, _
"Software\Microsoft\Internet Explorer\AboutURLs", "Home")
Form1.Caption = a

Для получения списка ключей в ключе используйте GetRegKeys

Пример:

Например, вам необходимо получить список ключей в подключе Software. Ф-ция GetRegKeys - возвращает значение типа Variant, содержащее одномерный массив со списком ключей. Поместите на форму список и введите примерно такой код:

Dim a As Variant
Dim c As Long
a = GetRegKeys(HKEY_LOCAL_MACHINE, "Software")
For c = 0 To UBound(a)
List1.AddItem a(c)
Next c

Для получения списка параметров в ключе используйте GetRegKeyValues

Пример:

Эта ф-ция как и предыдущая возвращает Variant - массив, но на этот раз 2-х мерный:

Dim a As Variant
Dim c As Long
a = GetRegKeyValues(HKEY_LOCAL_MACHINE, _
"Software\Microsoft\Windows\CurrentVersion\Run")
For c = 1 To UBound(a)
List1.AddItem a(c, 0)
List1.AddItem a(c, 1)
List1.AddItem "" 'Добавляем отступ для удобства
Next c

Здесь в массиве вторая размерность всегда равна 1. Т.е. 0 - отвечает за список параметров, а 1 за список их значений. Ну в общем запустите пример и сами поймёте.

Ф-ции записи:

Для записи строкового параметра используется SetRegString

Пример:

SetRegString HKEY_LOCAL_MACHINE, _
"Software\XYZ", "MyProgram", "Options"

Если ключ или параметр не были созданы, то они будут созданы. Если ключ или параметр уже существуют, то новые значения запишутся поверх старых.

Для записи параметра типа DWORD используется SetRegDWord

Пример:

SetRegDWord HKEY_LOCAL_MACHINE, _
"Software\XYZ", "MyProgram", "444"

Ф-ции удаления:

Для удаления ключа из реестра используется ф-ция DeleteRegKey

Пример:

DeleteRegKey HKEY_LOCAL_MACHINE, "Software", "XYZ", True

Второй параметр - Ключ-родитель

Третий параметр - True - если требуется подтверждение на удаление или False - если подтверждение не требуется.

Для удаления параметра из реестра используется ф-ция DeleteRegValue

Пример:

DeleteRegValue HKEY_LOCAL_MACHINE,_
"Software\Microsoft\Internet Explorer\AboutURLs", "mozilla", False

Желаю приятной работы с реестром Windows! :)


API Хитрости

Такой раздел есть практически на любом сайте посвящённым программированию на Visual Basic. Поэтому я тоже решил завести этот раздел. Вот несколько интересных хитростей, реализованных с помощью Windows API:

  • Перетаскивание формы за любое место
  • Программное UNDO в компоненте (например в TextBox или RichTextBox)
  • Отключение действия Ctrl+Alt+Del в Windows 9x (не в NT!)
  • Скрытие программы в списке задач Task Manager (т.е. в списке Ctrl+Alt+Del)
  • Программное открытие и закрытие CDROM'а
  • Вызвать окно свойств (Properties) файла

Перетаскивание формы за любое место:

Const WM_NCLBUTTONDOWN = &HA1
Const HTCAPTION = 2

Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" (ByVal hWnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
ReleaseCapture
SendMessage Form1.hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0
End Sub

Программное UNDO в компоненте (например в TextBox или RichTextBox)

Для создания UNDO просто необходимо послать сообщение WM_UNDO. Также можно послать сообщение EM_CANUNDO для определения возможности отмены. Пример: создайте новый проект, поместите на форму TextBox и кнопку. Вставьте этот код, и после запуска программы введите что-либо в TextBox и нажмите на кнопку.

Const WM_UNDO = &H304

Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" (ByVal hWnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
lParam As Any) As Long

Private Sub Command1_Click()
SendMessage Text1.hWnd, WM_UNDO, 0, 0
End Sub

Отключение действия Ctrl+Alt+Del в Windows 9x (не в NT!)

Declare Function SystemParametersInfo Lib "user32" Alias _
"SystemParametersInfoA" (ByVal uAction As Long, _
ByVal uParam As Long, ByVal lpvParam As Any, _
ByVal fuWinIni As Long) As Long

Для отключения реакции на Ctrl+Alt+Del:
SystemParametersInfo 97, True, ByVal 1&, 0

Для включения:
SystemParametersInfo 97, False, ByVal 1&, 0

Примечание: Не забудьте после закрытия программы снова включить реакцию на Ctrl+Alt+Del.

Скрытие программы в списке задач Task Manager (т.е. в списке Ctrl+Alt+Del)

Declare Function RegisterServiceProcess Lib "kernel32.dll" _
(ByVal dwProcessId As Long, ByVal dwType As Long) As Long

Declare Function GetCurrentProcessId Lib "kernel32.dll" () As Long

Для скрытия:
RegisterServiceProcess GetCurrentProcessId, 1

Для показа:
RegisterServiceProcess GetCurrentProcessId, 0

Программное открытие и закрытие CDROM'а

CDROM можно открывать и закрывать посылая текстовое сообщение ф-цией mciSendString, которая сидит в библиотеке winmm.dll.

Declare Function mciSendString Lib "winmm.dll" _
Alias "mciSendStringA" (ByVal lpstrCommand As String, _
ByVal lpstrReturnString As String, ByVal uReturnLength As Long, _
ByVal hwndCallback As Long) As Long

Открыть CD:
mciSendString "Set cdaudio door open wait", 0, 0, 0

Закрыть CD:
mciSendString "Set cdaudio door closed wait", 0, 0, 0

Вызвать окно свойств (Properties) файла (прислал Гриневич Дмитрий)

Declare Function ShellExecuteEX Lib "shell32.dll" Alias _
"ShellExecuteEx" (SEI As SHELLEXECUTEINFO) As Long
Const SEE_MASK_INVOKEIDLIST = &HC
Const SEE_MASK_NOCLOSEPROCESS = &H40
Const SEE_MASK_FLAG_NO_UI = &H400
Private Type SHELLEXECUTEINFO
cbSize As Long
fMask As Long
hwnd As Long
lpVerb As String
lpFile As String
lpParameters As String
lpDirectory As String
nShow As Long
hInstApp As Long
lpIDList As Long
lpClass As String
hkeyClass As Long
dwHotKey As Long
hIcon As Long
hProcess As Long
End Type

Public
        Sub
        ShowProps(FileName As String, OwnerhWnd As
        Long)
Dim SEI As SHELLEXECUTEINFO
Dim r As Long
With SEI
.cbSize = Len(SEI)
.fMask = SEE_MASK_NOCLOSEPROCESS Or _
SEE_MASK_INVOKEIDLIST Or SEE_MASK_FLAG_NO_UI
.hwnd = OwnerhWnd
.lpVerb = "properties"
.lpFile = FileName
.lpParameters = vbNullChar
.lpDirectory = vbNullChar
.nShow = 0
.hInstApp = 0
.lpIDList = 0
End With
r = ShellExecuteEX(SEI)
End Sub

Пример:

Private Sub Form_Load()
Call ShowProps("C:\AUTOEXEC.BAT", Me.hwnd)
End Sub


Разное полезное

В этом разделе вы найдёте другую полезную информацию, так или иначе касающуюся программирования на Visual Basic :) Описание ошибок, именование элементов, ASCII таблицу, виртуальные коды клавиш и т.д.


Именование элементов управления

При именовании элементов управления рекомендуется следовать стандартным соглашениям именования пользовательского интерфейса и элементов управления. Это позволяет упростить чтение и отладку программного кода. В именах элементов управления удобно проставлять префикс, однозначно указывающий на тип (класс) этого объекта. Ниже приведены рекомендуемые соглашения для некоторых элементов управления Visual Basic.

Тип элемента | Префикс | Пример
AniButton | ani | aniMailBox
CheckBox | chk | chkReadOnly
ComboBox | cbo | cboRussian
CommandButton | cmd | cmdExit
CommonDialog | dig | dIgFileOpen
Элемент управления (используется в процедурах, когда конкретный тип не определен) | ctr | ctrUnknown
Data control | dat | datOrders
Data-bound ComboBox | dbcbo | dbcboLanguage
Data-bound Grid | dbgrd | dbgrdQueryResult
Data-bound list box | dblst | dblstSchetType
Directory ListBox | dir | dirSource
Drive ListBox | drv | drvSource
File ListBox | fil | filSource
Form | frm | frmSchet
Frame | fra | fraLanguage
Gauge | gau | gauStatus
Grid | grd | grdTovar
Horizontal ScrollBar | hsb | hsbVolume
Image | img | imglcon
Label | Ibl | IblHelp
Line | lin | linVertical
ListBox | lst | lstOrder
MAPI message | mpm | mpmSentMessage


Таблица кодов клавиш (ASCII)

ASCII таблица и
Virtual KeyCodes

ASCII таблица кодов символов Windows (win.1251):

Dec | Hex | Символ
000 | 00 | спец. NOP
001 | 01 | спец. SOH
002 | 02 | спец. STX
003 | 03 | спец. ETX
004 | 04 | спец. EOT
005 | 05 | спец. ENQ
006 | 06 | спец. ACK
007 | 07 | спец. BEL
008 | 08 | спец. BS
009 | 09 | спец. Табуляция
010 | 0A | спец. LF (Возвр. каретки)
011 | 0B | спец. VT
012 | 0C | спец. FF
013 | 0D | спец. CR (Новая строка)
014 | 0E | спец. SO
015 | 0F | спец. SI
016 | 10 | спец. DLE
017 | 11 | спец. DC1
018 | 12 | спец. DC2
019 | 13 | спец. DC3
020 | 14 | спец. DC4
021 | 15 | спец. NAK
022 | 16 | спец. SYN
023 | 17 | спец. ETB
024 | 18 | спец. CAN
025 | 19 | спец. EM
026 | 1A | спец. SUB
027 | 1B | спец. ESC
028 | 1C | спец. FS
029 | 1D | спец. GS
030 | 1E | спец. RS
031 | 1F | спец. US
032 | 20 | сцеп. SP (Пробел)
033 | 21 | !
034 | 22 | "
035 | 23 | #
036 | 24 | $
037 | 25 | %
038 | 26 | &
039 | 27 | '
040 | 28 | (
041 | 29 | )
042 | 2A | *
043 | 2B | +
044 | 2C | ,
045 | 2D | -
046 | 2E | .
047 | 2F | /
048 | 30 | 0
049 | 31 | 1
050 | 32 | 2
051 | 33 | 3
052 | 34 | 4
053 | 35 | 5
054 | 36 | 6
055 | 37 | 7
056 | 38 | 8
057 | 39 | 9
058 | 3A | :
059 | 3B | ;
060 | 3C | <
061 | 3D | =
062 | 3E | >
063 | 3F | ?
064 | 40 | @
065 | 41 | A
066 | 42 | B
067 | 43 | C
068 | 44 | D
069 | 45 | E
070 | 46 | F
071 | 47 | G
072 | 48 | H
073 | 49 | I
074 | 4A | J
075 | 4B | K
076 | 4C | L
077 | 4D | M
078 | 4E | N
079 | 4F | O
080 | 50 | P
081 | 51 | Q
082 | 52 | R
083 | 53 | S
084 | 54 | T
085 | 55 | U
086 | 56 | V
087 | 57 | W
088 | 58 | X
089 | 59 | Y
090 | 5A | Z
091 | 5B | [
092 | 5C | \
093 | 5D | ]
094 | 5E | ^
095 | 5F | _
096 | 60 | `
097 | 61 | a
098 | 62 | b
099 | 63 | c
100 | 64 | d
101 | 65 | e
102 | 66 | f
103 | 67 | g
104 | 68 | h
105 | 69 | i
106 | 6A | j
107 | 6B | k
108 | 6C | l
109 | 6D | m
110 | 6E | n
111 | 6F | o
112 | 70 | p
113 | 71 | q
114 | 72 | r
115 | 73 | s
116 | 74 | t
117 | 75 | u
118 | 76 | v
119 | 77 | w
120 | 78 | x
121 | 79 | y
122 | 7A | z
123 | 7B | {
124 | 7C | |
125 | 7D | }
126 | 7E | ~
127 | 7F | 

Dec | Hex | Символ
128 | 80 | Ђ
129 | 81 | Ѓ
130 | 82 | ‚
131 | 83 | ѓ
132 | 84 | „
133 | 85 | …
134 | 86 | †
135 | 87 | ‡
136 | 88 | €
137 | 89 | ‰
138 | 8A | Љ
139 | 8B | ‹
140 | 8C | Њ
141 | 8D | Ќ
142 | 8E | Ћ
143 | 8F | Џ
144 | 90 | ђ
145 | 91 | ‘
146 | 92 | ’
147 | 93 | “
148 | 94 | ”
149 | 95 | •
150 | 96 | –
151 | 97 | —
152 | 98 | 
153 | 99 | ™
154 | 9A | љ
155 | 9B | ›
156 | 9C | њ
157 | 9D | ќ
158 | 9E | ћ
159 | 9F | џ
160 | A0 |
161 | A1 | Ў
162 | A2 | ў
163 | A3 | Ј
164 | A4 | ¤
165 | A5 | Ґ
166 | A6 | ¦
167 | A7 | §
168 | A8 | Ё
169 | A9 | ©
170 | AA | Є
171 | AB | «
172 | AC | ¬
173 | AD |
174 | AE | ®
175 | AF | Ї
176 | B0 | °
177 | B1 | ±
178 | B2 | І
179 | B3 | і
180 | B4 | ґ
181 | B5 | µ
182 | B6 | ¶
183 | B7 | ·
184 | B8 | ё
185 | B9 | №
186 | BA | є
187 | BB | »
188 | BC | ј
189 | BD | Ѕ
190 | BE | ѕ
191 | BF | ї
192 | C0 | А
193 | C1 | Б
194 | C2 | В
195 | C3 | Г
196 | C4 | Д
197 | C5 | Е
198 | C6 | Ж
199 | C7 | З
200 | C8 | И
201 | C9 | Й
202 | CA | К
203 | CB | Л
204 | CC | М
205 | CD | Н
206 | CE | О
207 | CF | П
208 | D0 | Р
209 | D1 | С
210 | D2 | Т
211 | D3 | У
212 | D4 | Ф
213 | D5 | Х
214 | D6 | Ц
215 | D7 | Ч
216 | D8 | Ш
217 | D9 | Щ
218 | DA | Ъ
219 | DB | Ы
220 | DC | Ь
221 | DD | Э
222 | DE | Ю
223 | DF | Я
224 | E0 | а
225 | E1 | б
226 | E2 | в
227 | E3 | г
228 | E4 | д
229 | E5 | е
230 | E6 | ж
231 | E7 | з
232 | E8 | и
233 | E9 | й
234 | EA | к
235 | EB | л
236 | EC | м
237 | ED | н
238 | EE | о
239 | EF | п
240 | F0 | р
241 | F1 | с
242 | F2 | т
243 | F3 | у
244 | F4 | ф
245 | F5 | х
246 | F6 | ц
247 | F7 | ч
248 | F8 | ш
249 | F9 | щ
250 | FA | ъ
251 | FB | ы
252 | FC | ь
253 | FD | э
254 | FE | ю
255 | FF | я

Таблица вмртуальных кодов клавиш Windows (Virtual Key Codes):

Константа WinApi | Hex значение | Клавиатурный или мышиный эквивалент
VK_LBUTTON | 01 | Left mouse button
VK_RBUTTON | 02 | Right mouse button
VK_CANCEL | 03 | Control-break processing
VK_MBUTTON | 04 | Middle mouse button (three-button mouse)
- | 05-07 | Undefined
VK_BACK | 08 | BACKSPACE key
VK_TAB | 09 | TAB key
- | 0A-0B | Undefined
VK_CLEAR | 0C | CLEAR key
VK_RETURN | 0D | ENTER key
- | 0E-0F | Undefined
VK_SHIFT | 10 | SHIFT key
VK_CONTROL | 11 | CTRL key
VK_MENU | 12 | ALT key
VK_PAUSE | 13 | PAUSE key
VK_CAPITAL | 14 | CAPS LOCK key
- | 15-19 | Reserved for Kanji systems
- | 1A | Undefined
VK_ESCAPE | 1B | ESC key
- | 1C-1F | Reserved for Kanji systems
VK_SPACE | 20 | SPACEBAR
VK_PRIOR | 21 | PAGE UP key
VK_NEXT | 22 | PAGE DOWN key
VK_END | 23 | END key
VK_HOME | 24 | HOME key
VK_LEFT | 25 | LEFT ARROW key
VK_UP | 26 | UP ARROW key
VK_RIGHT | 27 | RIGHT ARROW key
VK_DOWN | 28 | DOWN ARROW key
VK_SELECT | 29 | SELECT key
- | 2A | Original equipment manufacturer (OEM) specific
VK_EXECUTE | 2B | EXECUTE key
VK_SNAPSHOT | 2C | PRINT SCREEN key for Windows 3.0 and later
VK_INSERT | 2D | INS key
VK_DELETE | 2E | DEL key
VK_HELP | 2F | HELP key
VK_0 | 30 | 0 key
VK_1 | 31 | 1 key
VK_2 | 32 | 2 key
VK_3 | 33 | 3 key
VK_4 | 34 | 4 key
VK_5 | 35 | 5 key
VK_6 | 36 | 6 key
VK_7 | 37 | 7 key
VK_8 | 38 | 8 key
VK_9 | 39 | 9 key
- | 3A-40 | Undefined
VK_A | 41 | A key
VK_B | 42 | B key
VK_C | 43 | C key
VK_D | 44 | D key
VK_E | 45 | E key
VK_F | 46 | F key
VK_G | 47 | G key
VK_H | 48 | H key
VK_I | 49 | I key
VK_J | 4A | J key
VK_K | 4B | K key
VK_L | 4C | L key
VK_M | 4D | M key
VK_N | 4E | N key
VK_O | 4F | O key
VK_P | 50 | P key
VK_Q | 51 | Q key
VK_R | 52 | R key
VK_S | 53 | S key
VK_T | 54 | T key
VK_U | 55 | U key
VK_V | 56 | V key
VK_W | 57 | W key
VK_X | 58 | X key
VK_Y | 59 | Y key
VK_Z | 5A | Z key
VK_LWIN | 5B | Left Windows key (Microsoft Natural Keyboard)
VK_RWIN | 5C | Right Windows key (Microsoft Natural Keyboard)
VK_APPS | 5D | Applications key (Microsoft Natural Keyboard)
- | 5E-5F | Undefined
VK_NUMPAD0 | 60 | Numeric keypad 0 key
VK_NUMPAD1 | 61 | Numeric keypad 1 key
VK_NUMPAD2 | 62 | Numeric keypad 2 key
VK_NUMPAD3 | 63 | Numeric keypad 3 key
VK_NUMPAD4 | 64 | Numeric keypad 4 key
VK_NUMPAD5 | 65 | Numeric keypad 5 key
VK_NUMPAD6 | 66 | Numeric keypad 6 key
VK_NUMPAD7 | 67 | Numeric keypad 7 key
VK_NUMPAD8 | 68 | Numeric keypad 8 key
VK_NUMPAD9 | 69 | Numeric keypad 9 key
VK_MULTIPLY | 6A | Multiply key
VK_ADD | 6B | Add key
VK_SEPARATOR | 6C | Separator key
VK_SUBTRACT | 6D | Subtract key
VK_DECIMAL | 6E | Decimal key
VK_DIVIDE | 6F | Divide key
VK_F1 | 70 | F1 key
VK_F2 | 71 | F2 key
VK_F3 | 72 | F3 key
VK_F4 | 73 | F4 key
VK_F5 | 74 | F5 key
VK_F6 | 75 | F6 key
VK_F7 | 76 | F7 key
VK_F8 | 77 | F8 key
VK_F9 | 78 | F9 key
VK_F10 | 79 | F10 key
VK_F11 | 7A | F11 key
VK_F12 | 7B | F12 key
VK_F13 | 7C | F13 key
VK_F14 | 7D | F14 key
VK_F15 | 7E | F15 key
VK_F16 | 7F | F16 key
VK_F17 | 80H | F17 key
VK_F18 | 81H | F18 key
VK_F19 | 82H | F19 key
VK_F20 | 83H | F20 key
VK_F21 | 84H | F21 key
VK_F22 | 85H | F22 key
VK_F23 | 86H | F23 key
VK_F24 | 87H | F24 key
- | 88-8F | Unassigned
VK_NUMLOCK | 90 | NUM LOCK key
VK_SCROLL | 91 | SCROLL LOCK key
- | 92-B9 | Unassigned
- | BA-C0 | OEM specific
- | C1-DA | Unassigned
- | DB-E4 | OEM specific
- | E5 | Unassigned
- | E6 | OEM specific
- | E7-E8 | Unassigned
- | E9-F5 | OEM specific
VK_ATTN | F6 | Attn key
VK_CRSEL | F7 | CrSel key
VK_EXSEL | F8 | ExSel key
VK_EREOF | F9 | Erase EOF key
VK_PLAY | FA | Play key
VK_ZOOM | FB | Zoom key
VK_NONAME | FC | Reserved for future use.
VK_PA1 | FD | PA1 key
VK_OEM_CLEAR | FE | Clear key


Формат WAV файла

WAV файл - это звуковой файл формата RIFF. Он состоит из трёх заголовков, за которыми следуют данные самого звукового файла, т.е. последовательность байт самого звукового сигнала. Разберём все три заголовка подробнее:

Первый - RIFF заголовок. Он занимает 8 байт с самого начала файла и содержит следующую информацию (для удобства всё описано в структуре данных Visual Basic'а):

Type RIFF_HEAD
riffFmt As String * 4 ' Четыре буквы "RIFF"
lenOfFileData As Long ' длина файла без этого заголовка,
' т.е. FileLen(Wav) - 8
End Type

Второй заголовок - WAV заголовок. Вот его структура:

Type WAVE_HEAD
waveFmt As String * 8 ' 8 букв - "WAVEfmt "
lenOfThunk As Long ' размер этого куска (16 байт)
format As Integer ' формат WAV файла (обычно всегда 1)
channels As Integer ' кол-во каналов (1 - моно, 2 - стерео)
samplesPerSecond As Long ' зазрешение WAV файла,
' т.е. кол-во Samples'ов в сек (11025,22050,44100 и т.д.)
avgBytesPerSecond As Long ' тоже самое
blockAlign As Integer ' выравнивание блоков данных (обычно 1)
bitsPerSample As Integer ' Кол-во Битов на один сэмпл (8/16)
End Type

Ну и наконец третий, заголовок данных:

Type DATA_HEAD
datastr As String * 4 ' 4 буквы "data"
lenOfThunk As Long ' кол-во байт,
' отводящихся под сами WAV данные
End Type

Ну вот и всё, далее идут сами данные звукового файла. Если файл 2-х канальный, то данные идут по очереди, 1 канал, 2-ой, 1-ый, 2-ой... и т.д. Необходимо также помнить, что если файл 8 битный, то под каждый сэмпл отводится по одному байту, если же 16 битный - то по 2 байта. В конце файла иногда бывает некоторая дополнительная информация о WAV файле (имя Автора и т.д.), которую позволяют вносить программы типа Sound Forge. Ну вот и всё. Можете делать со звуковыми файлами различные чудеса! Для удобства можете использовать мой модуль для работы с WAV файлами. Модуль можно скачать здесь!


Регулярные выражения в VB

Что такое регулярные выражения (regular expressions)?

Регулярные выражения - это очень мощный механизм для обработки строк. С его помощью можно легко найти нужные части текста, проверить, удовлетворяет ли строка определённой маске, и т.д. и т.п. Такие выражения втроены во многие языки программирования, такие, как Perl, Php, JavaScript.

Что необходимо следать, чтобы такие выражения использовать в VB?

Для использования регулярных выражений в своих программах, необходимо подключить библиотеку Microsoft Windows Script. Такая библиотека поставляется с IE4 (и выше). Для подключения, зайдите в Project->References и поставьте флажок у VBScript Regular Expressions. Теперь к Visual Basic добавился объект RegExp, который содержит в себе все, что нужно для работы с регулярными выражениями.

Как использовать объект объект RegExp?

Для начала, необходимо объявить объектную переменную RegExp:

Dim myRegExp As New RegExp

Этот объект имеет следующие свойства и методы:

Свойства:

Global - если Global = True, то поиск ведётся во всей строке, если False, то только до первого совпадения.

IgnoreCase - игнорировать ли регистр символов при поиске.

Pattern - это свойство задаёт шаблон (маску) для поиска.

MultiLine - определяет, является ли текст многострочным или нет.

Методы:

Test - этот метод имеет следующий синтаксис:

Function Test(sourceString As String) As Boolean

Метод Test позволяет протестировать строку sourceString на соответствие её шаблону (Pattern). Возвращается Boolean, True - соответсвует, False - нет.

Execute - этот метод имеет следущий синтаксис:

Function Execute(sourceString As String) As MatchCollection

MatchCollection - это коллекция совпадений, которая содержит в себе всю информацию о всех совпадениях регулярного выражения в строке sourceString. Метод Execute может быть использован, например, для извлечения всех email адресов из строки sourceString.

Replace - этот метод имеет следующий синтаксис:

Function Replace(sourceString As String, replaceVar) _
As String

Метод Replace даёт возможность заменить все совпадения регулярного выражения строкой replaceVar.

Примеры использования регулярных выражений

Dim myRegExp As New RegExp ' создаём экземпляр RegExp'a
myRegExp.MultiLine = False ' текст однострочный
myRegExp.Global = True ' будем проходить всю строку
myRegExp.IgnoreCase = True ' игнорируем регистр символов
myRegExp.Pattern = "<BODY (.*)</BODY>" ' маска

Dim aMatch As Match ' один из совпавших образцов
Dim colMatches As MatchCollection ' коллекция этих образцов
Dim testString As String ' тестируемая строка

testString = "<HTML><BODY bgcolor=#FFAABB>" & _
"<P>Это пример</P></BODY></HTML>" ' текст для теста

Set colMatches = myRegExp.Execute(testString) ' запускаем!

For Each aMatch In colMatches ' проходим по всей коллекции
    List1.AddItem aMatch.FirstIndex
    List1.AddItem aMatch.Length
    List1.AddItem aMatch.SubMatches(0)
    List1.AddItem aMatch.Value
Next aMatch

В результате выполнения такого кода в ListBox (List1) добавятся вот такие строчки:

Первая - число 6 (FirstIndex) - это номер первого совпавшего символа (т.е. симола b)

Вторая строка - 46 (Length) - длина совпавшего образца.

Третья строка:
"bgcolor=#FFAABB><P>Это пример</P>". Это первый совпавший образец (\1), т.е. текст, попавший в скобки (.*) в маске. Для \2 нужно смотреть SubMatches(1) и т.д.

И последняя строка:
"<BODY bgcolor=#FFAABB><P>Это пример</P></BODY>" - полный образец.

Теперь, давайте, к примеру, изменим маску (регулярное выражение) так, чтобы из текста получить hex цвет (#XXXXXX). Маска может выглядить так:

"(#[0-9A-F]{6})"

Запустите и посмотрите что будет. Свойство SubMatches(0) вернёт вам строку - "#FFAABB", т.е. как раз то, что мы искали. Кстати, свойство Value вернёт вам такую же строку.

Рассмотрим пример использования метода Test:

Dim myRegExp As New RegExp
myRegExp.MultiLine = False
myRegExp.Global = True
myRegExp.IgnoreCase = True
myRegExp.Pattern = "(#[0-9A-F]{6})"

testString = "<HTML><BODY bgcolor=#FFAABB>" & _
"<P>Это пример</P></BODY></HTML>"

If myRegExp.Test(testString) Then
    MsgBox "Совпала!"
Else
    MsgBox "Не совпала."
End If

Здесь мы проверяем, совпала ли строка с регулярным выражением или нет.

И наконец, последний пример. Давайте заменим текст, находящийся в тегах <P> на другой текст:

myRegExp.Pattern = "<P>(.*?)</P>"
testString = "<HTML><BODY bgcolor=#FFAABB>" & _
"<P>Это пример</P></BODY></HTML>"
List1.AddItem myRegExp.Replace(testString, _
"<P>Новый текст в теге P!</P>")

В данном случае в тестируемой строке будет только одна пара <P></P>. Но вы можете сами добавить ещё одну пару и проверить работоспособность кода.

Синтаксис регулярных выражений

Здесь я разместил очень краткое описание синтаксиса регулярных выражений, т.к. подробное описание заняло бы не один десяток страниц. На эту тему была выпущена книга "Mastering Regular Expressions". Более подробное описание вы можете найти на специализированных сайтах. (www.perl.com, к примеру).

Спец. символы:

Символ | Назначение
* | Множитель. Определяет ни одного или несколько символов, стоящих перед ним. Пример: "ab*c" - символ a, затем ни одного или несколько символов b, и символ c.
. | Точка - любой одиночный символ, кроме символа новой строки. Например: "a." - символ a, за который следует любой одиночный символ.
[] | Скобки использутся для задания класса символов. Например: "[0-9A-F]" - соответствует одному hex символу. Заметьте, что 9-0 использовать нельзя! Символы должны идти обязательно по возрастающей.
[^] | Класс отрицания. Например: "[^A-Z]" - соответствует любому символу, крому любой заглавной латинской буквы.
\w | Любой буквенно-циферный символ. Фактически аналог класса: "[a-zA-Z0-9_]"
\W | Аналог "[^a-zA-Z0-9_]"
\d | Любая цифра: "[0-9]". Например "\d\d\.\d\d\.\d\d\d\d" - соответствует дате. Заметьте, что перед точкой нужно поставить обратную косую черту \. Это говорит о том, что точку мы хотим интерпретировать именно как точку, а не как спец. символ - точку.
\D | Аналог "[^0-9_]". Т.е. всё, кроме цифр.
\s | Пробельный символ "[ \r\t\n\f]".
\S | Непробельный символ "[^ \r\t\n\f]".
+ | Тоже множитель (как и *), но определяет один или более символов. Например: "ab+c" - символ a, один или более символов b и затем символ c.
? | Прожорливость. Например, выше, для замены текста внутри тегов <p> мы использовали следующую маску: "<P>(.*?)</P>". После * мы поставили знак вопроса. Если бы мы этого не сделати, что произошла бы замена всего того, что находится от первого тега <p> до последнего </p>. А так, происходит замена только до следующего тега.

Ещё несколько примеров регулярных выражений:

"(два|три) богатыря"
соответствует как строке "два богатыря", так и "три богатыря".

".+@.+\..+" - соответствует email адресу.

"a(.)\1c" - соответствует одному символу a, затем любым 2-м одинаковым символам, и затем символу с. Т.е. совпадёт "axxc", то не "axyc".

"(\d\d)\.\1\.\d\d\d\d" - соответствует дате, у которой число и месяц одинаковы. Т.е. дата "09.09.2001" - подойдёт, а дата "09.12.2001" - нет. Ну и т.п.


Описание операторов VB

Здесь подробно описаны все арифметические операторы, операторы сравнения, логические, а также операторы конкатенации. Я попытался собрать всё то, что необходимо знать об этих операторах. Каждый оператор снабжён примером. Описания переведены мной со стандартного Help'a VB5.

  • Арифметические:
    • ^ оператор возведения в степень
    • * оператор умножения
    • / оператор деления
    • \ оператор целочисленного деления
    • Mod оператор вычисления остатка от деления
    • + оператор сложения
    • - оператор вычитания
  • Сравнения:
    • < меньше
    • > больше
    • <= меньше или равно
    • >= больше или равно
    • = равно
    • <> не равно
    • Is оператор сравнения объектов
    • Like оператор сравнения строк
  • Конкатенации:
    • + оператор конкатенации
    • & оператор конкатенации
  • Логические:
    • And оператор логического умножения
    • Eqv оператор логической эквивалентности
    • Imp оператор логической импликации
    • Not оператор логического отрицания
    • Or оператор логического сложения
    • Xor оператор логического исключающего сложения

Арифметические операторы

оператор ^ (возведение в степень)

Этот оператор предназначен для возведения числа в степень.

Синтаксис:

результат = число ^ степень

Параметры:

результат - обязателен; любая числовая переменная
число - обязательно; любое числовое выражение
степень - обязателена; любое числовое выражение

Замечания:

число может быть отрицательное, только в том случае, когда степень - целое число. Если в одном выражении используется несколько операторов ^, то вычисление происходит слева направо. Обычно тип результата - Double. Однако, если или степень, или число - Null выражение, то результат тоже Null.

Пример:

Dim MyValue
MyValue = 2 ^ 2 ' Возвратит 4.
MyValue = 2 ^ 3 ^ 3 ' Возвратит 512 (2^3=8, 8^3=512)
MyValue = (-5) ^ 3 ' Возвратит -125.

Советы:

Если вам необходимо возвести число в постоянную степень, то лучше использовать несколько операторов - умножений, чем один - возведение в степерь, судите сами, цикл в миллион проходов с вычислением выражения проходил:

test1 = 2 ^ 8 ' 893мс
test1 = 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ' 130мс!

оператор * (умножение)

Используется для перемножения двух чисел.

Синтаксис:

результат = число1 * число2

Параметры:

результат - обязателен; любая числовая переменная
число1 - обязательно; любое числовое выражение
число2 - обязательно; любое числовое выражение

Замечания:

Тип данных результата обычно такой же, как и самый точный тип из двух чисел. Порядок точности, от большего к меньшему - Byte, Integer, Long, Single, Currency, Double, Decimal. Правда, есть исключения:

  • Если перемножаются Single и Long, то результат - Double
  • Если тип данных результата - Long Single или Date, в который не помещается сам результат выражения, то результат конвертируется в Variant, содержащий Double.

Если число1 или число2 - Null, то оно интерпретируется просто как обычный 0.

Порядок точности в умножение отличен от тех, что используются в сложении и вычитании.

Пример:

Dim MyValue
MyValue = 2 * 2 ' Возвратит 4.
MyValue = 459.35 * MyValue ' Возвратит 495.35 * 4

оператор / (деление)

Используется для деления двух чисел и получить результат с плавающей точкой.

Синтаксис:

результат = число1 / число2

Параметры:

результат - обязателен; любая числовая переменная
число1 - обязательно; любое числовое выражение
число2 - обязательно; любое числовое выражение

Замечания:

Результат обычно имеет тип Double. Правда, есть исключения:

  • Если оба выражения выражения имеют тип Byte, Integer, Single, то результат Single. Однако, если размеры выражения не вписываются в рамки Single, происходит ошибка.
  • Если оба выражения выражения имеют тип Variant, содержащий Byte, Integer или Single, то результат Single Variant. Однако, если размеры выражения не вписываются в рамки Single, то Double Variant.
  • Если одно из чисел имеет тип Decimal, то и результат - Decimal.

Если число1 или число2 - Null, то оно интерпретируется просто как обычный 0.

Примеры:

Dim MyValue
MyValue = 10 / 4 ' Возвратит 2.5.
MyValue = 10 / 3 ' Возвратит 3.333333.

оператор \ (целочисленное деление)

Используется для деления двух чисел и получить целочисленный результат.

Синтаксис:

результат = число1 \ число2

Параметры:

результат - обязателен; любая числовая переменная
число1 - обязательно; любое числовое выражение
число2 - обязательно; любое числовое выражение

Замечания:

Перед тем, как происходит такое деление, выражения округляются до Byte, Integer или Long выражений. Обычно тип данных результата Byte, Byte variant, Integer, Integer variant, Long, or Long variant. Любая дробная часть обрезается.

Однако, если любое из выражений Null, то и результат Null. Любое выражение, содержащее Empty интерпретируется как 0.

Примеры:

Dim MyValue
MyValue = 11 \ 4 ' Возвратит 2.
MyValue = 9 \ 3 ' Возвратит 3.
MyValue = 100 \ 3 ' Возвратит 33.

оператор Mod (остаток от деления)

Используется для деления двух чисел и получение остатка от их деления.

Синтаксис:

результат = число1 Mod число2

Параметры:

результат - обязателен; любая числовая переменная
число1 - обязательно; любое числовое выражение
число2 - обязательно; любое числовое выражение

Замечания:

При делении числа с правающей точкой округляются. Например, результат следующего выражения равен 5:

A = 19 Mod 6.7

Что здесь происходит? Сначала округляется число 6.7 до 7. Затем происходит деление, получаем 2.7.... Остаток от деления = 5. (2 * 7 = 14, 19 - 14 = 5).

Результат обычно имеет тип Byte, Byte variant, Integer, Integer variant, Long, или Variant содержащий Long.

Если любое из выражений Null, то и результат Null. Любое выражение, содержащее Empty интерпретируется как 0.

Примеры:

Dim MyResult
MyResult = 10 Mod 5 ' Возвратит 0.
MyResult = 10 Mod 3 ' Возвратит 1.
MyResult = 12 Mod 4.3 ' Возвратит 0.
MyResult = 12.6 Mod 5 ' Возвратит 3.

оператор + (сложение)

Используется для сложения двух чисел.

Синтаксис:

результат = выражение1 + выражение2

Параметры:

результат - обязателен; любая числовая переменная
выражение1 - обязательно; любое выражение
выражение2 - обязательно; любое выражение

Замечания:

Когда вы используете оператор +, вы не можете определить что произойдёт, сложение или конкатенация строк. Для конкатенации используйте оператор &, чтобы избежать недоразумений и сделать код более читабельным.

Если одно из выражений не Variant, то применяются следующие правила:

  • Если оба выражения имеют численный тип (Byte, Boolean, Integer, Long, Single, Double, Date, Currency, или Decimal) - то происходит их сложение.
  • Если оба выражения строки - конкатенация.
  • Если одно из выражений имеет численный тип, а другое любое Variant значение, включая Null, то происходит сложение.
  • Если одно из выражений строка, а другое любое Variant значение, то происходит конкатенация.
  • Если одно из выражений содержит Empty, то возвращается второе, не изменённое выражение.
  • Если одно из выражений имеет численный тип, а другое - строка, происходит ошибка несовпадения типов (Type mismatch).
  • Если любое выражение Null - тогда и результат тоже Null.

Если оба выражения Variant, то применяются следующие правила:

  • Если оба выражения числа - то они складываются.
  • Если оба выражения строки - то они конкатенируются.
  • Если одно из выражений число, а другое строка - происходит сложение.

Для обычного сложения тип данных результата обычно такой же, как и самый точный тип из двух чисел. Порядок точности следующий - Byte, Integer, Long, Single, Double, Currency, и Decimal. Есть исключения:

  • Если складываются Single и Long, то результат - Double
  • Если складываются выражение с типом Date, с любым другим выражением, то результат - Date.

Если одно или оба выражения Null, то результат тоже Null. Если оба из выражений содержат Empty, результат Integer. Если только одно, то в качестве результата возвращается не изменённое второе выражение.

Порядок точности в сложении и вычитании отличен от тех, что используются в умножении.

Примеры:

Dim MyNumber, Var1, Var2
MyNumber = 2 + 2 ' Возвратит 4.
MyNumber = 4257.04 + 98112 ' Возвратит 102369.04.

Var1 = "34"
Var2 = 6 ' Инициализируем смешанные переменные
MyNumber = Var1 + Var2 ' Возвратит 40.

Var1 = "34"
Var2 = "6" ' Инициализируем переменные со строками
MyNumber = Var1 + Var2 ' Возвратит "346" (произошла
' конкатенация, а не сложение!).

Советы:

Оператор сложение (+) можно использовать для сложения дат, т.е. переменных типа Date:

Dim
        d As Date
d = DateSerial(2002, 8, 15) ' иниализация даты 15.08.2002
d = d + 15 ' теперь d содержит дату 30.08.2002
' т.е. мы прибавили 15 дней

оператор - (вычитание, смена знака)

Используется для нахождения разницы между двумя числами, или, также, для изменения знака выражения.

Синтаксис:

результат = выражение1 - выражение2

или

-выражение

Параметры:

результат - обязателен; любая числовая переменная
выражение - обязательно; любое выражение
выражение1 - обязательно; любое выражение
выражение2 - обязательно; любое выражение

Замечания:

В первом синтаксисе, оператор "-" необходим для нахождения разницы между двумя числами. Во втором синтаксисе, "-" используется для смены знака у выражения.

Тип данных результата обычно такой же, как и самый точный тип из двух чисел. Порядок точности следующий - Byte, Integer, Long, Single, Double, Currency, и Decimal. Есть исключения:

  • Если в вычитании участвуют типы Single и Long, то результат - Double
  • Если в вычитании используется выражение с типом Date,
    то результат - Date.
  • Вычитание двух дат, даёт в результате Double.

Если одно или оба выражения Null, то результат тоже Null. Если одно из выражений Empty, то оно интерпретируется как 0.

Порядок точности в сложении и вычитании отличен от тех, что используются в умножении.

Примеры:

Dim MyResult
MyResult = 4 - 2 ' Возвратит 2.
MyResult = 459.35 - 334.90 ' Возвратит 124.45.

Советы:

Как и оператор сложение, оператор вычитание может быть применён для вычисления разницы (в днях) между двумя датами:

Dim
        d1 As Date
Dim d2 As Date
Dim razn As Long
d1 = DateSerial(1983, 10, 14)
d2 = DateSerial(2002, 8, 15)
razn = d2 - d1 ' разница в днях (6880).

Операторы сравнения

Используются для сравнения некоторых выражений. Имеют 3 синтаксиса:

Синтаксис:

результат = выражение1 операторсравнения выражение2
результат = объект1 Is объект2
результат = строка Like
        образец

Параметры:

результат обязателен; любая численная переменная
выражение обязательно; любое выражене
операторсравнения обязателен; любой оператор сравнения
объект обязателен; имя любого объекта
строка обязательна; любое строковое выражене.
образец обязателен; любое строковое выражение, или диапазон букв и цифр

Замечания:

Следующая таблица содержит список операторов сравнения и условия, по которым определяется результат выражения (True или False).

Оператор | True, если | False, если | Null, если
< (меньше чем) | выражение1 < выражение2 | выражение1 >= выражение2 | одно из выражений содержит Null
<= (меньше или равно) | выражение1 <= выражение2 | выражение1 > выражение2
> (больше чем) | выражение1 > выражение2 | выражение1 <= выражение2
>= (больше или равно) | выражение1 >= выражение2 | выражение1 < выражение2
= (равно) | выражение1 = выражение2 | выражение1 <> выражение2
<> (не равно) | выражение1 <> выражение2 | выражение1 = выражение2

Операторы Is и Like выполняют специфические функции, и их таблица сравнения отличается от приведённой (их мы рассмотрим ниже).

Когда сравниваются два выражения, не всегда можно определить, что будет сравниваться, числа или строки. Ниже показано, как будет вычислятся результат, если оба выражения имею тип, отличный от Variant:

  • Если оба выражения числа (Byte, Boolean, Integer, Long, Single, Double, Date, Currency, или Decimal), то происходит сравнение чисел.
  • Если оба выражения строки, то происходит сравнение строк. (меньшая строка та, первая и последующие буквы которой имею меньший ascii код).
  • Если одно из выражений число, а другое Variant, который может быть трактован как число, то происходит сравнение чисел.
  • Если одно из выражений число, а другое Variant строка, которая не может быть трактована как число, то происходит ошибка (Type mismatch).
  • Если одно из выражений строка, а другое любое Variant значение (даже Null), то происходит строковое сравнение.
  • Если одно из выражений Empty, а другое число, то происходит сравнение чисел, где Empty рассматривается как 0.
  • Если одно из выражений Empty, а другое строка, то происходит сравнение строк, где Empty рассматривается как пустая строка "".

Если и первое выражение и второе имеют тип Variant, то выражения сравниваются, согласно тем типам данных, которые содержит Variant:

  • Если оба Variant выражения содержат числа, то происходит сравнение чисел.
  • Если оба Variant выражения содержат строки, то происходит сравнение строк.
  • Если одно из Variant выражений содержит число, а другое строку, то числовое выражение меньше строкового.
  • Если одно из Variant выражений Empty, а другое число, то Empty рассматривается как 0.
  • Если одно из Variant выражений Empty, а другое строка, то Empty рассматривается как пустая строка "".
  • Если оба выражения Empty, то они рассматриваются как равные.

Когда Single переменная сравнивается с Double, то Double округляется до точности Single.

Если Currency сравнивается с Single или Double, то Single или Double конвертируются в Currency. Точно так же, при сравнении Decimal с Single или Double, то Single или Double конвертируются в Decimal. Для Currency любая дробная часть меньшая, чем .0001, может быть утеряна. Для Decimal это значение 1E-28, или может произойти ошибка. Таким образом, при потере дробной части, выражения могут интерпретироваться как равные, хотя на самом деле, одно от другого будет отличаться. (хоть и на маленькое значение).

Примеры:

Dim MyResult, Var1, Var2
MyResult = (45 < 35) ' Возвратит False.
MyResult = (45 = 45) ' Возвратит True.
MyResult = (4 <> 3) ' Возвратит True.
MyResult = ("5" > "4") ' Возвратит True.

Var1 = "5": Var2 = 4 ' в VB можно использовать двоеточие,
' для разделения операторов.
MyResult = (Var1 > Var2) ' Возвратит True.

Var1 = 5: Var2 = Empty
MyResult = (Var1 > Var2) ' Возвратит True.

Var1 = 0: Var2 = Empty
MyResult = (Var1 = Var2) ' Возвратит True.

оператор сравнения Is

Этот оператор используется для сравнения объктных переменных.

Синтаксис этого оператора приведён выше.

Замечания:

Если объект1 и объект1 ссылаются на один и тот же объект, то результат - True, если нет, то False. Две переменные могут ссылается на один и тот же объект несколькими путями. В следующем примере, A ссылается на тот же объект, что и B:

Set A = B

Следующий пример делает так, что переменные A и B ссылаются на один и тот же объект - C:

Set A = C
Set B = C

Примеры:

Dim MyObject, YourObject, ThisObject, _
OtherObject, ThatObject, MyCheck

Set YourObject = MyObject ' создаём ссылки на объекты
Set ThisObject = MyObject
Set ThatObject = OtherObject
MyCheck = YourObject Is ThisObject ' Возвратит True.
MyCheck = ThatObject Is ThisObject ' Возвратит False.
' Предполагаем, что MyObject <> OtherObject
MyCheck = MyObject Is ThatObject ' Возвратит False.

оператор сравнения строк - Like

Оператор сравнения строк Like используется для сравнения строк.

Синтаксис этого оператора уже рассмотрен выше.

Замечание:

Этот оператор можно использовать для проверки строки String на маску Pattern. Это очень мощный оператор, почти аналог регулярных выражений в Perl.

Итак, работает этот ператор следующим образом. Если строка подходит под маску, то результат True. Если нет - False. Если одно из выражений Null - результат тоже Null.

Поведение оператора Like зависит от установленного по умолчанию типа сравнения строк. (оператор Option Compare).

Если установлен тип Binary (т.е. двоичное сравнение), то строки сравниваются согласно их Ascii кодам (в разных кодировках она разная). Обычно используется такая последовательность:

A < B < E < Z < a < b < e < z < А < К < Я < а < к < я

Если установлен тип Text (текстовое сравнение). При таком сравнении последовательность отличается от предыдущей, здесь большие и маленькие буквы - равны:

(A=a) < (А=а) < (B=b) < (E=e) < (К=к) < (Z=z) < (Я=я)

Самое главная функция оператора Like - это проверка на принадлежность строки какой-нибудь маске. В маске можно использовать следующие спец. символы:

? Любой отдельный символ
* Ноли или более символов
# Любая цифра (0–9).
[charlist] Любой отдельный символ, попадающий в список charlist
[!charlist] Любой отдельный символ, непопадающий в список charlist

Здесь небольшое замечание. Для того чтобы проверить принадлежность строки на маске, содержащую спец. симолы (т.е. проверить, к примеру, есть ли в строке симолы [,?,#,],*), то нужно заключить из в квадратные скобки []. Просто так ставить отдельную скобку [ или ], нельзя.

При указании списка символов, можно использовать тире (–). Например, чтобы задать последовательность от A до Z, нужно использовать маску [A-Z]. Всё, что находится в скобках не должно содержать никаких разделителей (пробелов, запятых и т.д.), иначе они тоже будут включены в последовательность.

Есть и другие важные правила при проверки по маске:

  • (!) знак в начале списка символов говорит о том, что нужно искать символы, не входящие в этот список. Если вам необходимо найти сам знак !, то нужно поставить скобки [!].
  • (–) используется для задания диапазона символов.
  • Когда задаётся диапазон символов, то он должен быть возрастающим по ASCII кодам. Т.е. [A-Z] правильная маска, а [Z-A] нет.
  • Последовательность [] интерпретируется как пустая строка "".

Примеры:

Dim
        MyCheck
MyCheck = "aBBBa" Like "a*a"
        ' Возвратит True.
MyCheck = "F" Like "[A-Z]"
        ' Возвратит True.
MyCheck = "F" Like "[!A-Z]"
        ' Возвратит False.
MyCheck = "a2a" Like "a#a"
        ' Возвратит True.
MyCheck = "aM5b" Like "a[L-P]#[!c-e]"
        ' Возвратит True.
MyCheck = "BAT123khg" Like "B?T*"
        ' Возвратит True.
MyCheck = "CAT123khg" Like "B?T*"
        ' Возвратит False.

myString = "312T-87GD-8922"

If myString Like "###[A-Z]-##[A-Z][A-Z]-####" Then ...

Операторы конкатенации строк

Вообще-то, чтобы соединить строки в Visual Basic, можно использовать всего 2 оператора. Это & и +. Оператор + описан выше. Поговорим об операторе &.

оператор конкатенации строк - &

Используется для конкатенации двух выражений.

Синтаксис:

результат = выражение1 & выражение2

результат обязателен; Любая String или Variant переменная
выражение1 обязательно; Любое выражение
выражение2 обязательно; Любое выражение

Замечания:

Если в выражение не строка, то она конвертируется в String Variant. Тип данных результата - String только тогда, когда оба выражения имеют тип String. Иначе результат String Variant. Если оба выражения Null, то результат тоже Null. Однако, если только одно из выражений содержит Null значение, то оно интерпретируется как пустая строка "". Empty также интерпретируется как пустая строка "".

Примеры:

Dim MyStr
MyStr = "Hello" & " World"
' Возвратит строку "Hello World".
MyStr = "ПроВерКА" & 123 & " ПроВерка"
' Возвратит строку "ПроВерКА 123 ПроВерка".

Логические операторы

Это самая интересная группа оператором. При программировании вы обязаны знать их работу и применение (причём не только на Visual Basic).

В Visual Basic их 6 штук. Рассмотрим каждый оператор подробно.

оператор And

Используется для совершения логичкого умножения над двумя выражениями.

Синтаксис:

результат = выражение1 And выражение2

результат обязателен; Любая числовая (включая Boolean) переменная
выражение1 обязательно; Любое выражение
выражение2 обязательно; Любое выражение

Замечания:

Следующая таблица показывает как работает оператор And:

Если выражение1 = | , а выражение2 = | То результат =
True | True | True
True | False | False
True | Null | Null
False | True | False
False | False | False
False | Null | False
Null | True | Null
Null | False | False
Null | Null | Null

Оператор And также используется для проверки битов числа. Для битов оператор And работает следующим образом (смотреть слева направо)

0 0 0
0 1 0
1 0 0
1 1 1

Результат выделен жирным шрифтом.

Примеры:

Dim A, B, C, D, MyCheck
A = 10: B = 8: C = 6: D = Null
MyCheck = A > B And B > C ' Возвратит True.
MyCheck = B > A And B > C ' Возвратит False.
MyCheck = A > B And B > D ' Возвратит Null.
MyCheck = A And B ' Возвратит 8 (битовое сравнение).

Последний пример рассмотрим подробнее. Число 10 представляется в виде битов следущим образом (как тетрада, т.е. 4 бита):

1010

А число 8 вот так:

1000

В результате работы оператора And, согласно вышеприведённой таблице мы получим:

1000

Т.е. 8. Для чего мы это делали? Мы делали это для того, чтобы проверить, установлен ли четвёртый бит у числа A? Получив B, мы убедились в том, что этот бит установлен.

оператор Or

Используется для совершения логичкого сложения двух выражений.

Синтаксис:

результат = выражение1 Or выражение2

результат обязателен; Любая числовая (включая Boolean) переменная
выражение1 обязательно; Любое выражение
выражение2 обязательно; Любое выражение

Замечания:

Следующая таблица показывает как работает оператор Or:

Если выражение1 = | , а выражение2 = | То результат =
True | True | True
True | False | True
True | Null | True
False | True | True
False | False | False
False | Null | Null
Null | True | True
Null | False | Null
Null | Null | Null

Оператор Or используется для установки определённых битов числа. Для битов оператор Or работает следующим образом (смотреть слева направо)

0 0 0
0 1 1
1 0 1
1 1 1

Результат выделен жирным шрифтом.

Примеры:

Dim A, B, C, D, MyCheck
A = 10: B = 8: C = 6: D = Null
MyCheck = A > B Or B > C ' Возвратит True.
MyCheck = B > A Or B > C ' Возвратит True.
MyCheck = A > B Or B > D ' Возвратит True.
MyCheck = B > D Or B > A ' Возвратит Null.
MyCheck = A Or 5 ' Возвратит 15:

Давайте последний пример рассмотрим подробнее. Число 10 представляется в виде битов следущим образом (как тетрада, т.е. 4 бита):

1010

А число 5:

0101

В результате работы оператора Or, согласно вышеприведённой таблице мы получим:

1111

Т.е. 15. Как видите, оператор Or очень легко и удобно использовать не только в выражениях сравнения, но и для установки определённых битов числа.

оператор Xor

Используется для совершения логичкого отрицания двух выражений.

Синтаксис:

результат = выражение1 Xor выражение2

результат обязателен; Любая числовая (включая Boolean) переменная
выражение1 обязательно; Любое выражение
выражение2 обязательно; Любое выражение

Замечания:

Следующая таблица показывает как работает оператор Xor:

Если выражение1 = | , а выражение2 = | То результат =
True | True | False
True | False | True
False | True | True
False | False | False

Оператор Xor используется для инвертирования определённых битов числа. Для битов оператор Xor работает следующим образом (смотреть слева направо)

0 0 0
0 1 1
1 0 1
1 1 0

Результат выделен жирным шрифтом. Xor отличается от Or, только тем, что когда оба бита единицы, Xor выдаёт 0. Оператор Xor интересен тем свойством, то при его двойном применении он выдаёт то же число. Это часто используют в криптографии.

Примеры:

Dim A, B, C, D, MyCheck
A = 10: B = 8: C = 6: D = Null
MyCheck = A > B Xor B > C ' Возвратит False.
MyCheck = B > A Xor B > C ' Возвратит True.
MyCheck = B > A Xor C > B ' Возвратит False.
MyCheck = B > D Xor A > B ' Возвратит Null.
MyCheck = A Xor B ' Возвратит 2

Интересным примером использования оператора Xor является обмен значениями двух численных переменны:

Dim
        a As Long, b As Long
a = 4
b = 7
a = a Xor b
b = a Xor b
a = a Xor b

Теперь переменная a содержит значение переменной b, и наоборот. Подробнее данный фокус описан здесь.

оператор Not

Используется для совершения логичкого инвертирования двух выражений.

Синтаксис:

результат = Not выражение

результат обязателен; Любая числовая (включая Boolean) переменная
выражение обязательно; Любое выражение

Замечания:

Следующая таблица показывает как работает оператор Not:

Если выражение = | То результат =
True | False
False | True
Null | Null

Оператор Not инвертирует все биты выражения. Для битов оператор Not работает следующим образом (смотреть слева направо):

0 1
1 0

Результат выделен жирным шрифтом.

Примеры:

Dim A, B, C, D, MyCheck
A = 10: B = 8: C = 6: D = Null
MyCheck = Not(A > B) ' Возвратит False.
MyCheck = Not(B > A) ' Возвратит True.
MyCheck = Not(C > D) ' Возвратит Null.
MyCheck = Not A ' Возвратит -11 (все биты инвертированы)

Рассмотрим подробнее последний пример. Число 10 представляется в виде битов следущим образом (как байт, т.е. 8 битов):

0000 1010

После инвертирования всех битов получим:

1111 0101

А это и есть -11.

оператор Eqv

Используется для совершения логической эквивалентности двух выражений.

Синтаксис:

результат = выражение1 Eqv выражение2

результат обязателен; Любая числовая (включая Boolean) переменная
выражение1 обязательно; Любое выражение
выражение2 обязательно; Любое выражение

Замечания:

Следующая таблица показывает как работает оператор Eqv:

Если выражение1 = | , а выражение2 = | То результат =
True | True | True
True | False | False
False | True | False
False | False | True

Для битов оператор Eqv работает следующим образом (смотреть слева направо)

0 0 1
0 1 0
1 0 0
1 1 1

Примеры:

Dim A, B, C, D, MyCheck
A = 10: B = 8: C = 6: D = Null
MyCheck = A > B Eqv B > C ' Возвратит True.
MyCheck = B > A Eqv B > C ' Возвратит False.
MyCheck = A > B Eqv B > D ' Возвратит Null.
MyCheck = A Eqv B ' Возвратит -3

оператор Imp

Используется для совершения логической импликации двух выражений.

Синтаксис:

результат = выражение1 Imp выражение2

результат обязателен; Любая числовая (включая Boolean) переменная
выражение1 обязательно; Любое выражение
выражение2 обязательно; Любое выражение

Замечания:

Следующая таблица показывает как работает оператор Imp:

Если выражение1 = | , а выражение2 = | То результат =
True | True | True
True | False | False
True | Null | Null
False | True | True
False | False | True
False | Null | True
Null | True | True
Null | False | Null
Null | Null | Null

Для битов оператор Imp работает следующим образом (смотреть слева направо)

0 0 1
0 1 1
1 0 0
1 1 1

Примеры:

Dim A, B, C, D, MyCheck
A = 10: B = 8: C = 6: D = Null
MyCheck = A > B Imp B > C ' Возвратит True.
MyCheck = A > B Imp C > B ' Возвратит False.
MyCheck = B > A Imp C > B ' Возвратит True.
MyCheck = B > A Imp C > D ' Возвратит True.
MyCheck = C > D Imp B > A ' Возвратит Null.
MyCheck = B Imp A ' Возвратит -1


Описание событий VB

Здесь размещены подробные описания всех событий всех основных элементов управления, встроенных в Visual Basic. Сюда не входят события подключаемых элементов управления, таких например, как Microsoft Common Controls и т.п. Многие события снабжены примерами их использования. Всё переводилось мной со стандартного Help'а VB5.

В Visual Basic структура обработчика событий имеет следующую схему:

[Private | Public] Sub Объект_ИмяСобытия ([arglist])

End Sub

Внутри таких процедур и содержится основной код Visual Basic. Остальное находится в пользовательских функциях и процедурах.

Выберите интересующее вас событие:

  • Activate,Deactivate
  • Change
  • Click
  • DblClick
  • DragDrop
  • DragOver
  • Error
  • GotFocus
  • Initialize
  • ItemCheck
  • KeyDown, KeyUp
  • KeyPress
  • LinkClose,LinkError,LinkNotify,LinkOpen
  • Load
  • LostFocus
  • MouseDown, MouseUp
  • MouseMove
  • ObjectMove
  • OLECompleteDrag
  • OLEDragDrop
  • OLEDragOver
  • OLEGiveFeedback
  • OLEStartDrag
  • Paint
  • PathChange
  • PatternChange
  • QueryUnload
  • Reposition
  • Resize
  • Scroll
  • Terminate
  • Timer
  • Unload
  • Updated
  • Validate
Событие
Причина возникновения
Activate,Deactivate

Это событие имеет только форма.

Activate - вызывается в тот момент, когда форма становится активной (получает фокус). Однако, если перейти к другому приложению Windows, а затем вернуться к своему, то это событие не произойдёт. Оно срабатывает только при переключении между формами внутри программы.

Deactivate - Событие, обратное событию Activate. Вызывается при потере фокуса формы.
Change

ComboBox — меняется текст в текстовой части элемента. Происходит только тогда, когда свойство Style установлено в 0 (Dropdown Combo) или 1 (Simple Combo) и юзер изменяет текст или вы меняете его в коде программы.

DirListBox — Меняется выбранная директория. Происходит когда юзер делает двойной клик на новой директории или когда меняется свойство Path в коде.

DriveListBox — Меняется выбранное устройство. Происходит когда юзер меняет устройство, выбрав его из списка, или когда меняется свойство Drive в коде.

HScrollBar и VScrollBar (горизонтальная и вертикальная прокрутки) — Подвинулся скрол. Происходит когда юзер передвинул и отпустил полоску прокрутки или меняется свойство Value в коде.

Label — Меняется содержимое метки. Происходит когда меняется свойство Caption в коде.

PictureBox — Меняется содержимое PictureBox. Происходит при смене свойства Picture. (а также при использовании LoadPicture, прим.eax)

TextBox — Меняется текст в текстовом поле. Происходит при смене текста юзером или при смене свойства Text в коде.
Click

Происходит когда юзер нажимает и отпускает кнопку мышки над оъектом. Оно также может происходить при смене некоторого значения объекта.

Для формы такое собитие выполняется при клике на свободном месте формы, или по отключённому элементу управления (т.е. когда его Enabled = False).

Вообще событие происходит и для правой кнопки мыши и для левой. Но для элементов CheckBox, CommandButton, Listbox, и OptionButton происходит только при нажатии левой кнопки мыши.

Для ComboBox или ListBox оно происходит и при клике мышой и также при смене текущего элемента клавишами курсора.

Происходит при нажатии на "ПРОБЕЛ" у элементов CommandButton, OptionButton, или CheckBox, когда те имею фокус.

При нажатии на ENTER при фокусе на элементе CommandButton (то бишь гашей кнопке) и когда установлено свойство Default.

Происходит при нажатии на ESC когда форма имеет Cancel кнопку - CommandButton с установленым свойством Cancel.

Также происходит при нажатии на горячую последовательность. Например, если кнопка имеет Caption - "&Go", то при нажатии Alt+G запуститься событие.

Также, событие Click может быть сгенерировано в следующих случаях в коде: Установка значения Value для OptionButton и CheckBox.
DblClick

Происходит при двойном клике по объекту.

Для формы происходит при двойном клике по форме, а также по отключённому объекту.

Для других элементов:

Двойной клик по объекту левой кнопкой.

Двойной клик по элементу в ComboBox, когда Style = 1. Или также в FileListBox, ListBox, DBCombo, или DBList.
DragDrop

Происходит при завершении операции перетаскивания (Drag&Drop). В обработку события передаются 3 аргумента - координаты курсора (X,Y), где был отпущен объект, и ссылка на объект (Source), который был перетащен.
DragOver

Происходит когда объект перетаскивается над получателем, но кнопка ещё не отпущена. Имеет 4 параметра. Координаты курсора, ссылка на объект, и текущее состояние (State As Integer):

0 = Enter (вошёл) (источник вошёл в область объекта).
1 = Leave (покинул) (источник ушёл из этой области).
2 = Over (над) (произошёл сдвиг в пределах области).
Error

Происходит только при работе с базами данных. Коркретно: при ошибке в доступе к данным при выполнении кода.

Имеет 2 параметра:

dataerr - номер произошедшей ошибки
response - номер, соответствующий выбранному в настройках (Settings):

Если vbDataErrContinue, то response = 0 (Продолжить)
Если vbDataErrDisplay, то response = 1 (Default) Показать сообщение об ошибке.
GotFocus

Происходит, когда объект получает фокус, или при нажатии кнопки Tab или кликом по объекту, а также при запуске метода SetFocus в программе. Форма получает фокус только тогда, когда все видимые элементы отключены (Enabled = False).
Initialize

Это событие имеет только форма.

Обрабатывается первым и один раз. Visual Basic вызывает его при первом создании формы. Здесь обычно размещают код, для инициализации нужных переменны в программе.
ItemCheck

Происходит когда у ListBox контрола свойство Style установлено в 1 (checkboxes) и выбран или сброшен флажок у какого-либо элемента (item) в контроле.

Передаётся один параметр:

index - номер элемента, который был выбран в ListBox.
KeyDown, KeyUp

Происходит когда юзер нажимает (KeyDown) или отпускает (KeyUp) клавишу, в то время как объект имеет фокус. Чтобы получить код клавиши, используйте событие KeyPress. Параметров нет.
KeyPress

Происходит когда юзер нажамает и отпускает клавишу на клавиатуре.

Событие имеет один параметр:

keyascii - код нажатой клавиши. Например, если нажать на клавишу "1" (основного ряда), то keyascii будет равен 49. Если нажать ESC, то 27, и и.д.

Если присвоить этой переменной 0, то нажатая буква (символ) не появится в текством поле. Иногда это бывает очень удобным. Например, можно сделать так, чтобы в текстовое поле можно было вводить только цифры. Вот пример:

Таблицу кодов клавиш вы можете посмотреть здесь.
LinkClose
LinkError
LinkNotify
LinkOpen

LinkClose: Происходит когда DDE соединение закрывается. Может произойти в любое время.

LinkError: Происходит при возникновении ошибки в ходе связи DDE.

LinkNotify: Происходит когда у источника меняются данные, на которые установлена ссылка DDE.

LinkOpen: Происходит при создании инициализации DDE связи с источником.

За подробностями пожалуйста обращайтесь к справочникам, т.к. эти события используются очень редко.
Load

Это событие имеет только форма.

Обрабатывается при загрузке формы в память. Происходит после события Initalize. Обычно код испольняется один раз. При запуске программы, это событие обрабатывается автоматически для той формы, которая загружается первой.

Это событие может выполняться несколько раз. Т.е. если вы выгрузите форму оператором Unload, а затем вновь загрузите оператором Load или методом Show, то это событие будет выполнено.
LostFocus

Происходит при потере объектом фокуса, или при нажатии Tab юзером, или при использовании метода SetFocus для другого объекта.
MouseDown, MouseUp

Происходят когда юзер нажимает (MouseDown) или отпускает (MouseUp) кнопку мыши.

Имеют 4 передаваемых параметра:

button - содержит integer - номер кнопки мыши. С помощью этого события можно опеределить какую кнопку нажал пользователь. Для этого используюся константы: vbLeftButton (левая), vbMiddleButton (средняя), vbRightButton (правая). Проверить можно примерно так:

If button = vbRightButton Then ...

shift - содержит integer - указывающее на состояние клавиш Shift, Alt и Ctrl. Бит 0 - Shift, бит 1 - Ctrl, бит 2 - Alt. Для опредения факта нажатия клавиш Ctrl и Alt можно использовать такой код:

If (Shift And (vbCtrlMask Or vbAltMask)) = (vbCtrlMask Or vbAltMask) Then ...

Т.е. мы проверяем содержит ли переменная Shift биты 1 и 2 (оператором And). Скобки везде обязательны. vbShiftMask, vbAltMask, vbCtrlMask - это обычные константы, содержащие маски битов:

vbShiftMask = 1 (нулевой бит) Bin: 00000001
vbCtrlMask = 2 (первый бит) Bin: 00000010
vbAltMask = 4 (второй бит) Bin: 00000100

x, y - координаты курсора мыши того места, где произошло событие MouseUp или MouseDown. Координаты всегда зависят от координытной системы, задаваемой свойствами ScaleHeight, ScaleWidth, ScaleLeft, ScaleTop объекта.
MouseMove

Происходит когда курсор мыши изменяет своё положение над объектом. Т.е. когда курсор стоит на месте, событие не происходит. При каждом сдвиге курсора - срабатывает.

Параметры те же, что и у MouseDown и MouseUp.
ObjectMove

Происходит немедленно после того, как OLE контейнер сдвигается или меняет размеры пока объект активен.

Передаваемые параметры:

left - координата левой грани OLE контейнера
top - координата верхней грани OLE контейнера
width - ширина OLE контейнера
height - высота OLE контейнера
OLECompleteDrag

Происходит когда компонент - источник "брошен" на компонент - цель, информируя объект о том, что либо завершён, либо отменён процесс перетаскивания.

Имеет один параметр:

effect - привожу оригинал: A long integer set by the source object identifying the action that has been performed, thus allowing the source to take appropriate action if the component was moved (such as the source deleting data if it is moved from one component to another). The possible values are listed in Settings.

А Settings может быть:

vbDropEffectNone = 0 - операция "бросания" (Drop) была отменена.
vbDropEffectCopy = 1 - показывать значок копирования данных.
vbDropEffectMove = 2 - "сбрасываемые" данные являются ссылкой на оригинальные данные.
OLEDragDrop

Это событие происходит когда на объект сбрасываются OLE данные. Например, происходит при перетаскивании на объект файлов из проводника, или перетаскивании изображения из Internet Explorer и т.п.

Замечание: Это событие происходит только в том случае, когда свойство OLEDropMode установлено в 1 (Manual).

Имеет очень много параметров:

data - объект типа DataObject. Имеет 4 метода и одно свойство - коллекцию файлов, перетаскивамых на объект. Для получения данных можно использовать метод GetData. Чтобы узнать формат данных, перекинутых на объект можно использовать метод GetFormat.

effect Long - привожу оригинал - set by the target component identifying the action that has been performed (if any), thus allowing the source to take appropriate action if the component was moved (such as the source deleting the data). The possible values are listed in Settings.

button - то же, что и в событии MouseDown(Up).

shift - то же, что и в событии MouseDown(Up).

x,y - то же, что и в событии MouseDown(Up).

Пример. Обработаем перетащенные на форму файлы. Не забудьте установить свойство OLEDropMode в 1.

Private Sub Form_OLEDragDrop _
(Data As DataObject, Effect As Long, _
Button As Integer, Shift As Integer, _
X As Single, Y As Single)
' перетаскиваются файлы?
If Data.GetFormat(vbCFFiles) = True Then
Dim c As Long
' пройдёмся по всей коллекции
For c = 1 To Data.Files.Count
' покажем имя перетащенного файла
MsgBox "Был перетащен файл: " & Data.Files(c)
Next c
End If
End Sub
OLEDragOver
 Происходит при перетаскивании над объектом. Парметры - комбинация парамтров событий OLEDragDrop и обычного DragOver.
OLEGiveFeedback

Происходит после каждого события OLEDragOver. OLEGiveFeedback позволяет источнику обеспечивать визуальную "отдачу" пользователю, такое, как изменение курсора мыши (посмотрите на него при перетаскивании файлов в проводнике с нажатым Ctrl, - видите значок "+", вот это и есть та "отдача"?), которое будет говорить пользователю о том, что происходит.

Параметры - effect и

defaultcursors - boolean - разрешает или запрещает использование курсора по умолчанию. Если True - то используется курсор по умолчанию, если False, то использутся курсор, указанный пользователем в свойстве MousePointer объекта Screen.
OLEStartDrag

Происходит тогда, когда начинается перетаскивание (т.е. когда перетаскиваемый объект (файл, например) появляется над объектом приёмником). Имеет 2 параметры:

data - то же что и у события OLEDragDrop.

allowedeffects - Long - содержит поддерживаемые источником эффекты. Возможные значения описаны в Setting'сах.
Paint

Происходит когда часть или весь объект появляется на экране после сдвига или изменения размера. Событие происходит также при сдвиге окна, которое закрывает объект.

Разберём чуть подробнее:

Событие Paint полезно, если вы используете графические методы объекта (Line, PSet...) в коде. С помощью этого события вы можете убедиться в том, что данные перерисовались, когда это необходимо.

Событие Paint вызывается при запуске метода Refresh.

Если AutoRedraw установлено в True, то перерисовка происходит автоматически, таким образом, это событие теряет свою необходимость.

Если свойство ClipControls установлено в False, то графические методы в процедуре Paint воздействуют только на видимую часть формы; иначе, графические методы перерисовывают всю открытую часть формы (т.е. ту, которая не перекрыта такими элементами, как Image, Label, Line, и Shape).

Используя метод Refresh в событии Resize вызывает перерисовку всего объекта каждый раз, когда происходит изменение его размеров (Resize).

Замечание: Используя событие Paint для определённых задач, может произойти каскадирование событий (Т.е. просто напросто произойдёт рекурсия, когда Paint будет вызывать сам себя, и произойдёт переполнение стека). Чтобы этого избежать, нужно придерживаться следующих правил:

· Избегать вызова события Paint при сдвиге или изменении размеров объекта.
· Внутри события Paint изменять свойства, которые могут вызвать событие Paint. Такие, например, как BackColor.
· Включать метод Refresh метод внутрь Paint.
PathChange

Происходит при смене пути, установкой свойства FileName или Path в коде.

Замечание: Вы можете использовать это события, чтобы сообщить FileListBox'у о том, что путь у DirListBox изменился.
PatternChange

Происходит при изменении маски (такой, как "*.*") установкой свойств FileName или Pattern в коде.
QueryUnload

Это событие имеет только форма.

Происходит перед закрытием формы или приложения. Если закрывается MDI форма, то это событие происходит сначала для формы контейнера, и лишь потом для дочерних форм.

Это событие происходит перед событием Unload.

В обработчик данного события передаётся два параметра:

cancel - integer - если в обработчике события присвоить переменной cancel значение True, то выгрузка формы будет отменена. Если оставить там False, то форма благополучно выгрузится.

unloadmode - константа. Содержит значение - почему происходит выгрузка формы. Может принимать:

vbFormControlMenu = 0 - юзер выбрал команду Close (Закрыть) в меню приложения (слева вверху в заголовке формы).

vbFormCode = 1 - произошёл вызов оператора Unload в коде программы.

vbAppWindows = 2 - Windows завершает работу.

vbAppTaskManager = 3 - закрытие приложения происходит через Ctr+Alt+Del.

vbFormMDIForm = 4 - дочерняя MDI форма закрывается, т.к. закрывается главная.

Замечания:

Вообще, это событие обычно применяется для проверки завершённости некоторых действий. Или также, например, здесь можно спросить юзера, действительно ли он хочет выйти из приложения, или это произошло случаянно. Следать это можно примерно так:

Private Sub Form_QueryUnload _
(Cancel As Integer, _
UnloadMode As Integer)
Dim rez As VbMsgBoxResult
rez = MsgBox("Вы действительно" & _
" хотите выйти?", _
vbQuestion + vbYesNo)
If rez = vbNo Then Cancel = 1
End Sub
Reposition

Происходит когда запись становится текущей записью.

Замечания:

Когда Data контрол загружен, первая запись в объекте RecordSet становится текущей, и вызывается это событие. Когда бы юзер не кликнул любую кнопку на контроле Data, передвигаясь с записи на запись, или вы используете одно из методов Move в коде (такие, как MoveFirst, MoveNext, FindFirst..), или любое другое свойство, которое может изменить текущую запись - происходит событие Reposition.

Событие Validate происходит перед этим событием.
Resize

Происходит когда объект первый раз появляется или когда меняется состояние окна (например, при свёртывании и развёртывании окна). А также при смене размеров окна.

Это событие удобно использовать, если вы хотите сделать "растягивающийса" интерфейс. Т.е. когда все элементы на форме меняют свои размеры, в зависимости от текущих размеров формы. Код для изменения размеров этих элеметов как раз можно поместить в это событие.
Scroll

Происходит тогда, когда сдвигается полоса прокрутки (ScrollBar).

Замечания:

Для DBGrid это событие происходит, когда двигается вертикальная или горизонтальная полоса прокрутки.

Для ComboBox это событие происходит при сдвиге скролбара в выпадающем списке.

Вы можете использовать это события для синхронизации изменения положения полоски прокрутки и другими объектами, с которыми эта полоска связана. К примеру, в обработку этого события вставить код, который будет синхронизировать текущую позицию с другим элеметом. Поместите на форму HScroll и вставьте такой код:

Private Sub HScroll1_Scroll()
    Form1.Caption = HScroll1.Value
End Sub

Теперь в заголовок формы будет меняться в соответствии со сменой положения полоски прокрутки.

Кстати, избегайте использования фукнции MsgBox в этом событии!
Terminate

Это событие имеет только форма.

Происходит когда все ссылки на экземпляры форм, MDI форм, элементы управления, классы удалены из памяти (установкий переменной в Nothing).

Это событие выполняется после события Unload, и выполняется самым последним в программе. Можете использовать его по своему усмотрению.
Timer

Это событие имеется только у элемента управления Timer.

Оно происходит через определённый интервал времени, указанный в его свойтве Interval.

Timer невидим для пользователя, и полезен для внутренних процессов программы.

Его можно использовать когда необходимо, чтобы некоторый код программы выполнился через определённый промежуток времени.

Например, с его помощью можно сделать часы. Для этого достаточно поместить на форму элемент Timer, установите его свойство Interval в 1000 (1 сек = 1000 мс), и вставить следующий код:

Private Sub Timer1_Timer()
    Form1.Caption = Time
End Sub

Функция Time возвращает текущее системное время. Таким образом, каждую секунду будет выполнять событие Timer, и следовательно изменение заголовка формы.

Примечание: количесво таймеров на форме не ограничего.
Unload

Это событие имеет только форма.

Происходит когда форма выгружается из памяти (оператором Unload, например, или нажатием на крестик). В дальнейшем она может быть загружена оператором Load.

При перезагрузке формы ВСЕ ЭЛЕМЕНТЫ УПРАВЛЕНИЯ ИНИЦИАЛИЗИРУЮТСЯ ЗАНОВО, т.е. все значения, которые были в них - теряются.
Updated

Происходит когда меняются данные (при работе с БД).

Имеет параметр Code - integer - описывает, как объект был изменён (описано в настройках). Может принимать следующие константы:

vbOLEChanged = 0 - Данные объекта изменились
vbOLESaved = 1 - Данные объекта были сохранены приложением
vbOLEClosed = 2 - Файл, на который ссылается объект был закрыт
vbOLERenamed = 3 - Файл, на который ссылается объект был переименован
Validate

Это событие нужно для проверки введённых данных. Например, в TextBox. Это событие выполняется только тогда, когда свойство объекта CausesValidation = True.

Рассмотрим пример, как можно проконтролировать данные, введённые в текстовое поле. Поместите на форму TextBox и вставьте код:

Private Sub Text1_Validate _
(Cancel As Boolean)
    If Not (IsNumeric(Text1.Text)) Then
        Text1.ForeColor = vbRed
        MsgBox "Введите в TextBox числа"
        Cancel = True
    Else
        Text1.ForeColor = vbButtonText
    End If
End Sub

Этот код не примет введённый в TextBox текст, пока тот не будет являться числом. Если установить параметр Cancel в True, то фокус вернётся обратно TextBox.

Это событие происходит при потере фокуса у объекта.


Описание ошибок VB

Описание ошибок VB5

Ниже представлена таблица всех ошибок VB5 (только без SQL и Jet ошибок) из раздела trappable errors, т.е. отлавливаемые ошибки.

№ | English language | Русский язык
3 | Return without GoSub | Оператор Return без GoSub
5 | Invalid procedure call | Неверный вызов процедуры
6 | Overflow | Переполнение
7 | Out of memory | Не хватает памяти
9 | Subscript out of range | Индекс массива вышел за допусти--мые пределы
10 | This array is fixed or temporarily locked | Массив зафиксирован или временно недоступен
11 | Division by zero | Деление на ноль
13 | Type mismatch | Неверный тип
14 | Out of string space | Нет места для строки
16 | Expression too complex | Выражение слишком сложное
17 | Can't perform requested operation | Не могу выполнить запрашиваемую операцию
18 | User interrupt occurred | Произошло прерывание по указу пользователя
20 | Resume without error | Оператор Resume без ошибки
28 | Out of stack space | Нет места для стека
35 | Sub, Function, or Property not defined | Процедура, функция или свойство не определено
47 | Too many DLL application clients | Слишком много клиентов DLL приложения
48 | Error in loading DLL | Ошибка при загрузке DLL
49 | Bad DLL calling convention | Неверный вызов DLL
51 | Internal error | Внутренняя ошибка
52 | Bad file name or number | Неверное имя файла или неверный номер
53 | File not found | Файл не найден
54 | Bad file mode | Неверный тип доступа к файлу
55 | File already open | Файл уже открыт
57 | Device I/O error | Ошибка устройства ввода вывода
58 | File already exists | Файл уже существует
59 | Bad record length | Неверный размер записи
61 | Disk full | Диск переполнен
62 | Input past end of file | Чтение файла не возможно, т.к. достигнут его конец
63 | Bad record number | Неверный номер записи
67 | Too many files | Слишком много файлов
68 | Device unavailable | Устройство не доступно
70 | Permission denied | Доступ запрещён
71 | Disk not ready | Диск не готов
74 | Can't rename with different drive | Нельзя переименовать файл на другой носитель (т.е. оператором Name)
75 | Path/File access error | Ошибка доступа к файлу или каталогу
76 | Path not found | Каталог не найден
91 | Object variable or With block variable not set | Ссылка на объект или блок оператора With не установлен
92 | For loop not initialized | Не найдено начало цикла
93 | Invalid pattern string | Неверная маска
94 | Invalid use of Null | Неверное использование Null
97 | Can't call Friend procedure on an object that is not an instance of the defining class | Не могу вызывать процедуру Friend не являющуюся экземпляром класса
98 | A property or method call cannot include a reference to a private object, either as an argument or as a return value (Error 98) | Обращение к свойство или методу не может включать ссылку на Private объект. Этот объект также не может быть в качестве аргумента или возвращаемого значения.
298 | System DLL could not be loaded | Системная DLL не может быть загружена
320 | Can't use character device names in specified file names | Не могу использовать в качестве имени файла название порта
321 | Invalid file format | Неверный формат файла
322 | Can’t create necessary temporary file | Не могу создать необходимый временный файл
325 | Invalid format in resource file | Неверный формат файла ресурсов
327 | Data value named not found | Значение не можен быть найдено
328 | Illegal parameter; can't write arrays | Недопустимый параметр; не могу записать массив
335 | Could not access system registry | Не могу получить доступ к реестру
336 | ActiveX component not correctly registered | ActiveX компонент неправильно зарегистрирован
337 | ActiveX component not found | ActiveX компонент не найден
338 | ActiveX component did not run correctly | ActiveX компонент не правильно запущен (?)
360 | Object already loaded | Объект уже загружен
361 | Can't load or unload this object | Не могу загрузить или выгрузить объект
363 | ActiveX control specified not found | ActiveX компонент не найден
364 | Object was unloaded | Объект был выгружен
365 | Unable to unload within this context | В данном случае невозможно выгрузить объект
368 | The specified file is out of date. This program requires a later version | Данный файл устарел. Эта программа требует более новой версии
371 | The specified object can't be used as an owner form for Show | Данный объект не может быть использован как родитель формы для её показа
380 | Invalid property value | Неверное значение свойства
381 | Invalid property-array index | Неверный индекс свойства-массива
382 | Property Set can't be executed at run time | Процедура установки свойства не может быть запущена во время работы программы
383 | Property Set can't be used with a read-only property | Процедура установки свойства не может быть использована для свойств, доступных только для чтения
385 | Need property-array index | Необходим индекс для свойства-массива
387 | Property Set not permitted | Процедура установки свойства не разрешена
393 | Property Get can't be executed at run time | Процедура чтения свойства не может быть запущена во время работы программы
394 | Property Get can't be executed on write-only property | Процедура чтения свойства не может быть использована для свойств, доступных только для записи
400 | Form already displayed; can't show modally | Форма уже показана; не могу показать форму модально
402 | Code must close topmost modal form first | Код должен сначала закрыть модальную форму самого высшего уровня
419 | Permission to use object denied | Запрещено использование данного объекта
422 | Property not found | Свойство не найдено
423 | Property or method not found | Свойство или метод не найден
424 | Object required | Необходим объект
425 | Invalid object use | Неверное использование объекта
429 | ActiveX component can't create object or return reference to this object | ActiveX компонент не может создать объект или возвратить ссылку на этот объект
430 | Class doesn't support Automation | Класс не поддерживает технологию Automation
432 | File name or class name not found during Automation operation | Имя файла или класса не найдено в процессе операции Automation
438 | Object doesn't support this property or method | Объект не поддерживает данное свойство или метод
440 | Automation error | Ошибка Automation
442 | Connection to type library or object library for remote process has been lost | Связь с библиотекой типов или библиотекой объектов для удалённого процесса была утеряна
443 | Automation object doesn't have a default value | Automation объект не имеет значения по умолчанию
445 | Object doesn't support this action | Объект не поддерживает данную операцию
446 | Object doesn't support named arguments | Объект не поддерживает названные аргументы
447 | Object doesn't support current locale setting | Объект не поддерживает текущие локальные настройки
448 | Named argument not found | Названный аргумент не найден
449 | Argument not optional or invalid property assignment | Аргумент обязателен или неверное присваивание свойству
450 | Wrong number of arguments or invalid property assignment | Неверное количество аргументов или неверное присваивание свойству
451 | Object not a collection | Объект - это вам не коллекция :)
452 | Invalid ordinal | Неверное числительное
453 | Specified DLL function not found | Данная функция DLL не найдена
454 | Code resource not found | Ошибка для макинтошей (это такие компы разноцветные)
457 | This key is already associated with an element of this collection | Этот ключ уже ассоциирован с элементом коллекции
458 | Variable uses a type not supported in Visual Basic | Переменная использует неподдер-живаемый Visual Basic'ом тип
459 | This component doesn't support the set pf events | Единственный раз в жизни я увидел опечатку в Microsoft'овской документации! Слева вместо pf должно стоять of! А ошибка переводится примерно так: Не для всех компонентов можно использовать оператор WithEvevents и Implements.
460 | Invalid Clipboard format | Неверный формат буфера обмена
461 | Specified format doesn't match format of data | Данный фармат не совпадает с форматом данных
480 | Can't create AutoRedraw image | Не могу создать AutoRedraw изображение
481 | Invalid picture | Неверное изображение
482 | Printer error | Ошибка принтера
483 | Printer driver does not support specified property | Драйвер принтер не поддерживает данное свойство
484 | Problem getting printer information from the system. Make sure the printer is set up correctly | Проблема при чтении информации принтера в системе. Убедитесь, что принтер правильно установлен
485 | Invalid picture type | Неверный тип изображения
486 | Can't print form image to this type of printer | Не могу распечатать изображение формы на таком типе принтера
520 | Can't empty Clipboard | Не могу очистить буфер обмена
521 | Can't open Clipboard | Не могу открыть буфер обмена
735 | Can't save file to TEMP directory | Не могу сохранить файл в директорию TEMP (временную)
744 | Search text not found | Искомый текст не найден
746 | Replacements too long | Текст для замещение слишком длинный
31001 | Out of memory | Не хватает памяти
31004 | No object | Нет объекта
31018 | Class is not set | Класс не установлен
31027 | Unable to activate object | Не могу активизировать объект
31032 | Unable to create embedded object | Не могу создать внедрённый объект
31036 | Error saving to file | Ошибка записи в файл
31037 | Error loading from file | Ошибка чтения из файла


Что может Visual Basic?

В принципе, возможности Visual Basic ничем не ограничены. Вы можете расширять возможности VB посредством использования дополнительных функций. Visual Basic позволяет использовать библиотеки динамической компоновки (DLL библиотеки), которые также могут широко расширить возможности Visual Basic. Эти библиотеки могут быть написаны на любом языке программирования.

На VB можно написать любую программу, от обслуживающих рутинные операции ввода данных, до сложных информационных и коммуникационных систем. В США 60% программных продуктов написаны на VB. Есть конечно очень небольшие ограничения, например, на VB нельзя написать полноценную DLL библиотеку, драйвер устройства VXD, также в VB нельзя использовать ассемблер. Но когда вам понадобятся эти вещи, вы можете написать их на другом языке и, затем, использовать их в VB. Так что просторы VB очень велики!

Теперь можно приступать к установке и настройке VB!


Visual Basic - Крепкий Орешек!

Описание меню IDE

Описание меню

Для справки наведите мышкой на интересующий элёмент меню (совет: чтобы всплывающая подсказка не исчезала (а она пропадает секунд через 5, после бездействия мыши) сдвигайте мышку на пару пикселов, тогда будет всё нормально))

File
Новый проект. Этой командой открывается окно диалога, с помощью которого можно создать новый проект. При этом пользователю будет предложено выбрать тип проекта. Набор предлагаемых типов зависит от варианта (издания) пакета Visual Basic 5.0. Открыть проект. С помощью этой команды можно открыть и загрузить существующий проект. Стандартный диалог Open Project содержит две вкладки (Existing и Recent), которые позволяют выбирать либо один из вообще существующих проектов, либо один из последних, с которыми работал пользователь. Добавить проект. Создает или открывает еще один проект, не закрывая текущий. При этом появляется окно диалога, предлагающее выбрать либо тип нового проекта (вкладка New), либо существующий проект, который необходимо открыть параллельно уже открытым (вкладки Existing и Recent). Таким образом можно открыть несколько проектов одновременно и создать группу проектов. Удалить проект. Закрывает текущий проект. Сохранить проект Сохранить проект под новым именем Сохранить... - Сохраняет текущий элемент проекта на диске. Многоточие представляет здесь имя элемента проекта, который является текущим. Сохранить... под именем - Сохраняет текущий элемент проекта на диске под новым именем. Печать. Открывает окно диалога, позволяющее вывести на принтер форму или программный код. Установка параметров печати. Открывает окно диалога, позволяющее изменить параметры печати. Создать исполняемый файл. Создает исполняемый (ЕХЕ, DLL или OCX) файл текущего проекта (многоточие представляет здесь имя файла). При этом открывается окно диалога Make Project, позволяющее задать имя исполняемого файла, а также открыть диалог Project Options (Параметры проекта), где в свою очередь можно задать параметры компиляции (например, компиляция в машинный код или в Р-код и Др.). Создать исполняемые файлы для проектов группы. Создает исполняемые (ЕХЕ, DLL или OCX) файлы всех проектов текущей группы. Список последних открытых проектов. Далее в меню File следует список проектов, которые открывались последними (до четырех). Открыть любой из них можно щелчком на соответствующем пункте. Выход из VB

Edit
«Откатывает» (отменяет) последнюю выполненную операцию, т. е. восстанавливает состояние, которое имело место до нее. Откат отката. Восстанавливает состояние, которое имело место перед выполнением команды Undo. Удаляет выделенную область и копирует ее в буфер обмена. Эта и остальные операции буфера выполнимы как применительно к тексту, так и к управляющим элементам при редактировании экранной формы. Копирует выделенную область в буфер обмена. Вставляет содержимое буфера обмена в текущую позицию курсора (если речь идет о тексте) или в область левого верхнего угла формы (если речь идет об управляющих элементах). Устанавливает связь OLE и DDE-элементов, находящихся на редактируемой форме, с OLE и DDE-объектами из других приложений. Удаляет выделенную область или (если ничего не выделено) символ справа от курсора. При редактировании формы, если ничего не выделено, будет удален текущий элемент. Выделяет все содержимое текущего окна. Открывает диалоговое окно, позволяющее найти первое или все вхождения строки символов в текстовом окне. Продолжает поиск, начатый командой Find. Открывает окно диалога, позволяющее заменить строку (или все строки) в текущем окне, которые удовлетворяют заданному образцу, на заданную в этом же окне строку. Сдвигает все строки в выделенном фрагменте текста на следующую позицию табуляции. Сдвигает все строки в выделенном фрагменте текста на предыдущую позицию табуляции. Открывает окно диалога, позволяющее открыть текстовой файл и вставить его содержимое в текущей позиции курсора. Открывает в окне кода список свойств и методов, определенных для объекта, имя которого предшествует точке (.). Свойство или метод можно при этом выбрать и вставить после точки (.). Открывает в окне кода список констант, которые могут быть присвоены в качестве значения свойству, имя которого предшествует знаку равенства (=), Константу можно при этом выбрать и вставить справа от знака равенства (=). Дает краткую подсказку относительно синтаксиса функции, процедуры или метода, на имени которого находится курсор в окне кода. Дает краткую подсказку относительно параметров функции, процедуры или метода, на имени которого находится курсор в окне кода. Вызывает диалог всплывающей подсказки, для продолжения текущего слова. Это подменю содержит четыре команды, которые позволяют устанавливать и убирать закладки, а также перемещаться между ними в окне кода.

View
Открывает или делает видимым окно кода, относящееся к текущей форме или модулю. Открывает или делает видимым окно формы, которая является текущей. Переходит на то место в окне кода, где определяется переменная или процедура, на имени которой находится курсор. Позволяет вернуться в то место кода, которое непосредственно перед этим подвергалось редактированию. Visual Basic запоминает 8 таких позиций. Открывает список объектов (типов, классов, констант, методов, свойств и событий), которые пользователь может использовать в своей программе. Список также содержит имена процедур и модулей, уже имеющихся в программе. Открывает окно Immediate, используемое при отладке программ. Открывает окно Locals, где при отладке программ отображаются значения переменных. Открывает окно Watches, где при отладке программ отслеживаются значения выражений, определенных пользователем. Служит для просмотра последовательности вызовов процедур, которая привела к текущему состоянию программы. Открывает окно проекта. Открывает окно свойств. Открывает окно, отображающее положение формы на экране, каким оно будет при выполнении программы. Открывает окно диалога с несколькими вкладками, дающими доступ к свойствам выбранного управляющего элемента. Открывает или делает видимым окно коллекции инструментов. Открывает окно диалога, позволяющее выбрать цвет текущего элемента или формы. Это подменю содержит пять команд, управляющих наличием на экране панелей инструментов Visual Basic, а также команду Customize (Настройка), которая позволяет создать новую панель инструментов или изменить настройки IDE в том, что касается имеющихся панелей инструментов, а также панели главного меню

Project
Открывает окно диалога, позволяющее включить в состав проекта новую или существующую форму. Открывает окно диалога, позволяющее включить в состав проекта новую или существующую материнскую MDI-форму. Проект может содержать только одну материнскую MDI-форму, поэтому после ее включения данная команда становится недоступной. Позволяет включить в состав проекта новый или существующий программный модуль. Позволяет включить в состав проекта модуль, содержащий определения классов. Visual Basic разрешает пользователю создавать управляющие элементы. Для включения таких элементов в состав проекта и предназначена эта команда. Позволяет включить в состав проекта страницу свойств. Visual Basic дает возможность создавать страницы свойств для новых или существующих определяемых пользователем управляющих элементов. Эта команда доступна только при работе над ActiveX-элементом (проекты типа ActiveX EXE или ActiveX DLL). Она позволяет включить в состав проекта пользовательский документ, который предназначен для взаимодействия с программой Internet Explorer или другим броузером, поддерживающим технологию ActiveX. Команда становится доступной после того, как в диалоге Components (меню Project) будет подключен хотя бы один конструктор AxtiveX. Включает существующий файл в состав проекта, при этом один и тот же файл может быть включен в состав нескольких проектов. Любые изменения, внесенные в файл, отразятся во всех проектах одновременно. Многоточие здесь представляет текущий элемент проекта. В результате выполнения этой команды соответствующий элемент будет исключен из состава проекта. Открывает окно диалога, которое позволяет включить в проект ссылки на библиотеки объектов, классов и элементы других проектов. Ссылки позволяют обращаться в коде к объектам из других приложений. Открывает окно диалога, позволяющее для данного проекта включить в состав коллекции инструментов управляющие элементы, конструкторы и другие объекты (например, документы Word). Многоточие здесь представляет имя текущего проекта. Открывает окно свойств проекта, позволяющее их изменить . Диалог состоит из четырех вкладок.

Format
Это подменю содержит ряд команд, предназначенных для выравнивания выделенной группы элементов. За исключением команды То Grid, все команды этого подменю доступны лишь в случае, если на форме выделена группа (не менее двух) управляющих элементов. Подменю содержит команды, которыми можно уравнять размеры выделенных элементов (при этом за «образец» берется элемент, выделенный последним — элемент с темными размерными маркерами) В результате выполнения этой команды размеры выделенных элементов будут изменены так, чтобы их вертикальные и горизонтальные грани совпадали с ближайшими линиями сетки. Эти два подменю содержат идентичные наборы команд, предназначенных для изменения свободных промежутков между выделенными элементами по горизонтали/вертикали Две команды этого подменю позволяют переместить центры выделенных элементов на центральную вертикальную либо горизонтальную линию формы. Меняет положение выделенных элементов относительно остальных элементов формы Все управляющие элементы, размещенные на текущей форме, блокируются — переместить их с помощью мыши невозможно.

Debug
Эта команда выполняет один оператор программы. Если текущий оператор — вызов процедуры, следующим текущим оператором станет первый оператор процедуры. Эта команда также выполняет один оператор программы. Но если текущий оператор — вызов процедуры, то следующим текущим оператором станет первый оператор после вызова процедуры. Если текущим оператором является один из операторов процедуры, то в результате выполнения этой команды будут выполнены все оставшиеся операторы процедуры. Будут выполнены все строки, начиная с текущей и кончая той, в которой находится курсор. Затем программа перейдет в режим останова (ее выполнение будет приостановлено). Открывает окно диалога, позволяющее определить выражение, значение которого можно будет наблюдать при отладке. Открывает окно диалога, позволяющее отредактировать или удалить наблюдаемое выражение. Открывает окно диалога, позволяющее узнать значение выражения, которое не было ранее определено как отслеживаемое (в диалоге Add Watch). Устанавливает (или снимает ранее установленную) точку разрыва в позиции текущей строки. Снимает все ранее установленные точки разрыва в отлаживаемой программе. Позволяет принудительно сделать текущей произвольную строку исходного текста отлаживаемой программы. В результате выполнения этой команды будет выделен оператор, который должен получить управление после текущего.

Run
Запускает программу. Осуществляет полную компиляцию проекта и запускает программу. Прерывает выполнение программы и переводит IDE в режим прерывания (режим пошаговой отладки). Завершает выполнение программы. Перезапускает выполяющуюся программу. При этом программа стартует с начала, все переменные заново инициализируются.

Tools
Открывает окно диалога, помогающее программисту создать процедуру, функцию, свойство или событие. Позволяет установить атрибуты для свойств и методов объекта. Открывает окно редактора меню, позволяющее присоединить меню к текущей форме. Открывает окно диалога (шесть вкладок), позволяющее менять параметры и настройки IDE.

Add-ins

Add-Ins (внешние утилиты, запускаемые из среды IDE) позволяют расширять возможности IDE Visual Basic практически безгранично. Все варианты Visual Basic 5 позволяют включать вызов внешних утилит (надстроек) в меню Add-Ins, а профессиональные варианты позволяют также эти утилиты создавать. Поэтому содержимое меню Add-Ins зависит как от варианта (издания) Visual Basic, так и от того, какие пункты включил в него пользователь. Как минимум, это меню включает в себя один «обязательный» пункт: Add-In Manager (администратор внешних утилит), который, собственно, и дает возможность включать в это меню новые команды.

Window
(С этим меню всё понятно, оно стандартно. Да и вообще редко используется)

Help
Запускает справочную систему и выводит на экран окно диалога (три вкладки), позволяющее найти нужный раздел. Дает доступ к набору «книг» — учебников и справочников, освещающих различные аспекты программирования на языке Visual Basic. Эта команда запускает справочную систему, которая предлагает пользователю разнообразную информацию об услугах корпорации Microsoft в сфере поддержки своих программных продуктов. Список WWW-адресов, по которым имеющий доступ к Internet пользователь может получить полезные сведения о Visual Basic (доступ возможен непосредственно из среды Visual Basic). Выводит на экран сведения, касающиеся лицензии на данную копию Visual Basic. Добавить проект к текущему Добавить новую форму (окно) Функции буфера обмена и поиска Undo/Redo Play :) Эта кнопка запускает вашу программу Остановка программы для использования пошагового режима Стоп, т.е. завершить работу вашей программы Активизирует окно Project Активизирует окно Properties Активизирует окно Layout Открывает Object Browser Активизирует панель с элементами управления Вызывает редактор меню вашего приложения. Открыть проект Сохранить проект Координаты левого верхнего угла текущего элемента управления Ширина и высота текущего элемента управления

Описание панели инструментов:

Первая половина:

Вторая половина:


Visual Basic - Крепкий Орешек!

Управляющие структуры языка

Этот раздел посвящён операторам, которые предназначены для управления процессом выполнения всех остальных исполняемых операторов Visual Basic. Такие классические структуры, как устловные операторы и операторы цикла, имеются во всех процедурных языках программирования, имеются они и в Visual Basic.

Условный оператор If...End If

В этой конструкции некоторые операторы выполняются только при условии, содержащееся в конструкции логическое выражение имеет значение True (истинно):

If Логическое_выражение Then Оператор

или сложнее

If Логическое_выражение Then
Группа_операторов
End If

В первом случает оператор может быть только один. Во втором сколько угодно (в том числе и один).

Пример:

If (a = b) And (c <> d) Then
b = d
a = 20
End If

Скобки здесь не обязательны, но они повышают читабельность кода.

Условный оператор If...Else...ElseIf...End If

Такая конструкция используется для более сложных ветвлений:

If Логическое_выражение 1 Then
Группа_операторов
ElseIf Логическое_выражение 2 Then
Группа_операторов
...
Else
Группа_операторов
End If

Эта схема может быть и в укороченном виде If...Then...Else...End If. При этом операторы после Else выполняются только в том случае, если ни одно из условий не выполнено.

Пример:

If (a = b) Or (c <> d) Then
b = d
a = 20
Else
c = d
End If

Выражение c=d будет выполнено только в том случае, если a<>b или c=d.

Условный оператор Select Case...End Select

Конструкция Select Case "принимает решение" на основе анализа значения одного выражения. При этот это выражение указывается в строке Select Case:

Select Case Анализируемое_выражение

Case Значение№1
Группа операторов
Case Значение№2
Группа операторов
...
Case Значение№N
Группа операторов
Case Else
Группа операторов

End Select

Конечно, анализируемое выражение должно возвращать значение типа, совместимого с типом значений в строка Case.

Пример:

В зависимости от значения переменной iTest, строковой переменной strResult присваиваются различные значения

Select Case iTest

Case 1
strResult = "iTest = 1"
Case 2, 3, 4
strResult = "iTest = 2, 3 или 4"
Case 5 To 9
strResult = "iTest находится в диапазоне от 5 до 9"
Case iTest < 0
strResult = "iTest меньше 0"
Case Is > 9
strResult = "iTest больше 9"
Case Else
strResult = "iTest равно 0"

End Select

Оператор цикла For...Next

Этот цикл используют в том случае, когда заранее известно стартовое и конечное значение счётчика. Синтаксис выглядит следующим образом:

For Счётчик_цикла = Старт To Стоп Step Шаг
Группа операторов
Next [Счётчик_цикла]

Роль счётчика цикла может играть только ранее объявленная переменная целочисленного типа. Шаг задаёт приращение счётчика цикла при каждом проходе. Умолчательно значение шага равно 1. После слова Next счётчик можно опустить.

Пример:

В этом примере всем элементам массива iArray присваивается значение 5.

Dim c As Integer
Dim iArray(10) As Integer
For c = 0 To 10
iArray(c) = 5
Next c

Оператор цикла For Each...Next

Эта специфическая форма цикла For предназначена для выполнения некоторой операции с каждым объектом, входящим в состав некоторой коллекции объектов (такой операцией, например, может быть вызов метода или присваивание значения свойству). Синтаксис оператора:

For Each ИмяОбъекта In ИмяКоллекции
Операции над объектами
Next ИмяОбъекта

Пример:

В этом примере показано, как изменить свойство BackColor у всех этикеток (Label), лежащих на форме

Dim x As Object
For Each x In Me.Controls
If TypeName(x) = "Label" Then
x.BackColor = 0
End If
Next x

Оператор цикла Do While...Loop / Do...Loop While

Эти две разновидности цикла тесно взаимосвязаны, и их часто рассматривают как один из базовых видов цикла. Как уже отмечалось, циклы For применяют в тех случаях, когда количество проходов и диапазон изменения счётчика цикла заранее известны. Циклы While предназначены для ситуаций, когда количество проходов цикла заранее не известно, но зато известно условие выхода из цикла. Синтаксис цикла While:

Do While Условие_выхода
Группа операторов
Loop

Do
Группа операторов
Loop While Условие_выхода

Отличие между ними заключается в том, что условие выхода проверяется в одном случае перед очередным проходом, а в другом случае - после выхода. Если в цикле опустить условие выхода или это условие всегда выполняется, то получится бесконечный цикл. Например вот такой

Do While 2 > 1
Degub.Print "Вечный цикл"
Loop

Если у вас случаянно получился такой цикл, то выйти из него можно при нажатии Ctrl+Break. Но это работает только в среде разработки.

Пример:

Dim n As Integer
n = 100
Do While n >= 0
n = n - 1
Debug.Print n
Loop

Оператор цикла Do Until...Loop / Do...Loop Until

По своей логике цикл Until подобен циклу While с той лишь разницей, что проходы цикла выполняются до тех пор, пока условие выхода не выполняется.

Пример:

Dim n As Integer
n = 100
Do
n = n - 1
Debug.Print n
Loop Until n < 11

Выход из цикла Exit For / Exit Do

С помощью операторов Exit... можно осуществить досрочный выход из цикла вне зависимости от значения, которое имеет в данный момент условие выхода.

Пример:

Dim n As Integer
n = 10
Do While n > 1
n = n - 1
Debug.Print n
If n = 5 Then Exit Do ' Если счётчик = 5, то выходим из цикла
Loop